Hugo<![CDATA[Decaf Blog]]> 2024-04-12T20:16:03+00:00 https://blog.decaf200.com/ <![CDATA[Automating SSL Certificate Renewal with Certbot]]> https://blog.decaf200.com/posts/text-file-processing/ 2024-04-12T00:00:00+00:00 2024-04-12T00:00:00+00:00 Automating SSL Certificate Renewal with Certbot

Certbot is an automated tool that simplifies the way webmasters can obtain, renew, and manage SSL certificates. It interacts with the Let’s Encrypt CA through a protocol called ACME (Automated Certificate Management Environment), allowing the certificates to be issued and renewed without significant user interaction.

Setting Up Certbot

Before you can renew your SSL certificates with Certbot, you need to have it installed on your server. This can typically be done through package managers on systems like Ubuntu (sudo apt-get install certbot) or CentOS (sudo yum install certbot).

Using Certbot for Renewal

Certbot provides a hassle-free mechanism to renew SSL certificates. To automate the renewal process, you should run the following command:

Plain textANTLR4BashCC#CSSCoffeeScriptCMakeDartDjangoDockerEJSErlangGitGoGraphQLGroovyHTMLJavaJavaScriptJSONJSXKotlinLaTeXLessLuaMakefileMarkdownMATLABMarkupObjective-CPerlPHPPowerShell.propertiesProtocol BuffersPythonRRubySass (Sass)Sass (Scss)SchemeSQLShellSwiftSVGTSXTypeScriptWebAssemblyYAMLXML bashCopy codecertbot renew

This command checks all certificates installed on the server and renews them if they are within 30 days of expiration. It’s a good practice to test this process with a dry run:

Plain textANTLR4BashCC#CSSCoffeeScriptCMakeDartDjangoDockerEJSErlangGitGoGraphQLGroovyHTMLJavaJavaScriptJSONJSXKotlinLaTeXLessLuaMakefileMarkdownMATLABMarkupObjective-CPerlPHPPowerShell.propertiesProtocol BuffersPythonRRubySass (Sass)Sass (Scss)SchemeSQLShellSwiftSVGTSXTypeScriptWebAssemblyYAMLXML bashCopy codecertbot renew --dry-run

The --dry-run option simulates the renewal process without making any actual changes to your certificates, ensuring everything works as expected.

Automating the Process

While running certbot renew is straightforward, remembering to do so regularly might not be practical. Therefore, automating this process is critical. You can achieve this by scheduling a cron job that runs certbot renew twice a day. Here is an example of a cron job entry that you might add to your server’s crontab file:

Plain textANTLR4BashCC#CSSCoffeeScriptCMakeDartDjangoDockerEJSErlangGitGoGraphQLGroovyHTMLJavaJavaScriptJSONJSXKotlinLaTeXLessLuaMakefileMarkdownMATLABMarkupObjective-CPerlPHPPowerShell.propertiesProtocol BuffersPythonRRubySass (Sass)Sass (Scss)SchemeSQLShellSwiftSVGTSXTypeScriptWebAssemblyYAMLXML javascriptCopy code0 12,0 * * * /usr/bin/certbot renew --quiet

This cron job runs at noon and midnight every day, renewing any certificates that need it and doing so quietly without generating output.

Ensuring Reliability

After setting up Certbot to renew certificates automatically, it’s wise to monitor your system’s logs (usually found in /var/log/letsencrypt) to ensure that renewals are proceeding as expected. Occasionally, issues such as network interruptions or changes in the Let’s Encrypt API might require your attention.

]]>
<![CDATA[Text files processing in CLI]]> https://blog.decaf200.com/posts/certbot/ 2024-04-11T00:00:00+00:00 2024-04-11T00:00:00+00:00 Small article on how to process text files in CLI

1. Viewing Text Files

Before processing text files, you might need to view their contents. You can use commands like cat, less, more, and tail:

  • cat filename.txt: Displays the entire contents of the file.

  • less filename.txt: Allows for scrollable viewing of the file contents.

  • more filename.txt: Similar to less, but with less flexibility.

  • tail -n 10 filename.txt: Shows the last 10 lines of the file.

2. Searching Text Files

To search within a text file, grep is incredibly useful:

  • grep “search_string” filename.txt: Prints lines containing the search string.

  • grep -i “search_string” filename.txt: Case-insensitive search.

  • grep -r “search_string” /path/: Recursively search all files under the specified directory.

3. Editing Text Files

While Bash isn’t typically used for interactive editing, you can use sed for stream editing:

  • sed ’s/old/new/g’ filename.txt: Replaces all occurrences of ‘old’ with ’new’ in the file and displays the result.

  • To save changes back to the file, you can redirect the output: sed ’s/old/new/g’ filename.txt > modified_filename.txt

4. Sorting Data in Text Files

Sorting content is another common requirement:

  • sort filename.txt: Sorts lines alphabetically.

  • sort -r filename.txt: Sorts lines in reverse order.

  • sort -n filename.txt: Sorts lines numerically.

5. Unique Lines in Text Files

To find or filter unique lines, use uniq:

  • sort filename.txt | uniq: Removes duplicate lines (note that uniq requires sorted input).

  • sort filename.txt | uniq -u: Displays only unique lines that do not have duplicates.

6. Counting Words, Lines, and Characters

The wc command is useful for getting basic statistics:

  • wc filename.txt: Displays the line, word, and character counts.

  • wc -l filename.txt: Counts the number of lines in the file.

7. Extracting Columns of Data

The cut command is handy when dealing with delimited data:

  • cut -d’,’ -f1 filename.txt: Extracts the first column from a CSV (comma-separated values) file.

8. Combining Multiple Files

To combine the contents of multiple text files, use cat:

  • cat file1.txt file2.txt > combined.txt: Concatenates file1.txt and file2.txt into combined.txt.

9. Transforming Text

You can use tr to translate or delete characters:

  • cat filename.txt | tr ‘[:lower:]’ ‘[:upper:]’: Converts all lowercase letters to uppercase.

  • tr -s ’ ’ < filename.txt: Squeezes multiple spaces into a single space.

10. Redirecting and Appending Output

Understanding redirection is crucial:

  • command > file.txt: Redirects the output of command to file.txt, overwriting it.

  • command » file.txt: Appends the output of command to file.txt.

]]>
<![CDATA[LFTP command description]]> https://blog.decaf200.com/posts/lftp/ 2024-02-12T00:00:00+00:00 2024-02-12T00:00:00+00:00 Useful lftp commands

LFTP is more than your average FTP client. It supports a wide range of protocols, including FTP, HTTP, HTTPS, SFTP, and BitTorrent. This versatility makes it an invaluable tool for interacting with various servers and services. What sets LFTP apart is its commitment to reliability and efficiency, offering features like automatic retries, background operations, and scriptable commands.

Features That Set LFTP Apart

  • Multiprotocol Support: LFTP’s ability to handle FTP, HTTP, SFTP, and even BitTorrent protocols makes it incredibly versatile for any file transfer need.
  • Parallel Downloads: LFTP can download several files in parallel, significantly speeding up the transfer process for multiple files.
  • Automatic Retry: It intelligently retries failed downloads, ensuring that your files are transferred successfully without manual intervention.
  • Mirroring Capabilities: With LFTP, mirroring entire directories or websites is simplified, preserving the file structure and ensuring an exact copy is made.
  • Scriptable and Automatable: Its command-line nature allows for powerful scripting capabilities, enabling users to automate complex transfer scenarios and routine backup tasks.

Getting Started with LFTP

Diving into LFTP begins with its installation, which is straightforward on most Unix-like operating systems, often available directly from the package manager. Once installed, initiating an LFTP session is as simple as typing lftp followed by the server’s address. From there, the world of advanced file transfers is at your fingertips.

Advanced Usage and Tricks

  • Segmented Downloading: LFTP can split a file into multiple segments, downloading them concurrently for faster completion times.
  • Scheduling Transfers: Combine LFTP with cron jobs to schedule your file transfers during off-peak hours, optimizing bandwidth usage.
  • Scripting Magic: Write LFTP scripts to automate routine tasks, such as syncing directories or backing up data, and execute them with lftp -f script_name.

Real-World Applications

The true power of LFTP shines in scenarios requiring robust file transfer capabilities. System administrators can leverage its mirroring feature to create backups of entire websites, while data analysts might use it to automate the retrieval of large datasets from remote servers. Its ability to resume interrupted transfers also makes it ideal for working with unreliable connections.

]]>
<![CDATA[Useful Wget commands]]> https://blog.decaf200.com/posts/wget-commands/ 2023-02-22T00:00:00+00:00 2023-02-22T00:00:00+00:00 Collection of wget commands

Basic Download Operations

  • wget [URL]: At its simplest, wget followed by the URL downloads the file to your current directory, preserving the original filename.
  • -O, --output-document=[FILE]: This command lets you specify a custom filename for the downloaded file instead of using the one from the URL.

Downloading in the Background

  • -b, --background: Use this to run wget in the background, freeing your terminal for other tasks. It logs the progress into wget-log or a specified logfile.

Recursive Downloading

  • -r, --recursive: This command is perfect for downloading entire websites or parts of websites, mirroring all the directory structure.
  • -l, --level=[NUMBER]: Limits the recursion depth. Useful for controlling how deep you go into a website’s link hierarchy.

Controlling the Rate of Download

  • --limit-rate=[RATE]: Slows down the download speed to a specified rate, ensuring it doesn’t hog all your bandwidth.

Resuming Interrupted Downloads

  • -c, --continue: Resumes a partially downloaded file, picking up where it left off without starting from scratch.

Specifying Download Times

  • --start-time=[TIME]: Schedules the download to begin at a specific time. This is useful for initiating downloads during off-peak hours.

Adjusting Retry Behavior

  • -t, --tries=[NUMBER]: Sets the number of retries for a failed download. Use -t 0 for infinite retries.
  • --retry-connrefused: Retries even if the connection is refused.

Downloading in a Specific Directory

  • -P, --directory-prefix=[PREFIX]: Directs wget to save the file(s) to a specified directory, organizing your downloads better.

Website Authentication

  • --http-user=[USER] and --http-password=[PASSWORD]: These commands are critical for downloading files from password-protected websites, ensuring secure access.

HTTPS and SSL Verification

  • --no-check-certificate: Disables SSL certificate verification, useful for sites with self-signed certificates.

Setting User Agent

  • -U, --user-agent=[AGENT]: Mimics a specific browser or bot, which can be necessary for downloading from sites that restrict by user agent.

Using Proxy

  • -e, --execute="http_proxy=[URL]": Configures wget to use a proxy for the download, essential for navigating through network restrictions.
]]>
<![CDATA[Check URL status]]> https://blog.decaf200.com/posts/check-url/ 2022-11-11T00:00:00+00:00 2022-11-11T00:00:00+00:00 Check URL status from Bash

Copy env variables to script:

curl \
    --output /dev/null \
    --silent \
    --write-out "%{http_code}" \
    "https://decaf200.com"
]]>
<![CDATA[Text files cleanup]]> https://blog.decaf200.com/posts/text-cleanup/ 2022-01-30T00:00:00+00:00 2022-01-30T00:00:00+00:00 Text files cleanup and content deduplication

Sort file lines and deduplicate content:

sort file.txt | uniq -u

Usage of AWK for deduplicate file content:

awk '!seen[$0]++' file.txt
]]>
<![CDATA[DNS dig commands]]> https://blog.decaf200.com/posts/dig-dns/ 2021-12-30T00:00:00+00:00 2021-12-30T00:00:00+00:00 Dig DNS commands

Fetch A record for domain:

dig google.com

Query specific DNS server:

dig @8.8.8.8 google.com

Fetch ANY DNS record

dig google.com ANY

Fetch MX records:

dig MX google.com

DNS trace command:

dig google.com +trace
]]>
<![CDATA[Useful bash scripts]]> https://blog.decaf200.com/posts/bash-blocks/ 2021-11-10T00:00:00+00:00 2021-11-10T00:00:00+00:00 Collection of useful bash scripts

Copy env variables to script:

#!/usr/bin/env bash

Strict mode for execution of code:

set -euo pipefail

Script conditional arguments:

if [[ -z "$string" ]]; then
  echo "String is empty"
elif [[ -n "$string" ]]; then
  echo "String is not empty"
fi

Range loops:

for i in {1..5}; do
    echo "Id: $i"
done

Example function:

function myfunc() {
    echo "Example $1"
}
myfunc "Arg"
]]>
<![CDATA[Useful Curl commands]]> https://blog.decaf200.com/posts/curl-commands/ 2021-10-13T00:00:00+00:00 2021-10-13T00:00:00+00:00 Useful CURL commands with examples

Send Post request:

curl --data "key1=value1&key2=value2" http://site.com

Send JSON data:

curl  -H 'Content-Type: application/json' --data '{"param1":"test1","param2":"test2"}' http://test.com

Get status code:

curl -s -o /dev/null -w "%{http_code}" http://www.example.org/
]]>
<![CDATA[List of useful text transformation commands]]> https://blog.decaf200.com/posts/text-transformation-commands/ 2021-07-16T00:00:00+00:00 2021-07-16T00:00:00+00:00 List of commands useful to transform text files in bash

Convert encoding:

iconv  -f CP1252 -t UTF-8 example.txt > example-utf-8.txt

Xrumer files conversion from windows encoding to UTF-8

iconv  -f windows-1251 -t UTF-8//IGNORE example.txt > example-utf-8.txt
iconv  -f windows-1251 -t UTF-8//IGNORE  4Success.txt > utf8/4Success.txt

Text wiles cleanup, remove duplicates and empty lines:

awk 'NF && !seen[$0]++' inputfile.txt > outputfile.txt
grep -v "^[[:space:]]*$" in.txt | uniq

Count number of lines in file:

wc -l file.txt

Split files by lines:

split -l <number-of-lines-in-file> file.txt
  • will be generated xa* each with lines

Find and remove files:

find . -name "Success.txt" -exec rm -rf {} \;

find . -name "Success.txt" | xargs rm -rf 
]]>
<![CDATA[List of popular User Agents]]> https://blog.decaf200.com/posts/user-agents/ 2021-07-15T00:00:00+00:00 2021-07-15T00:00:00+00:00 Post with list of most popular user agents

Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36
Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:90.0) Gecko/20100101 Firefox/90.0
Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:91.0) Gecko/20100101 Firefox/91.0
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Safari/605.1.15
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.1 Safari/605.1.15
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36
Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:90.0) Gecko/20100101 Firefox/90.0
Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:90.0) Gecko/20100101 Firefox/90.0
Mozilla/5.0 (Windows NT 10.0; rv:78.0) Gecko/20100101 Firefox/78.0
Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:91.0) Gecko/20100101 Firefox/91.0
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36 Edg/92.0.902.67
Mozilla/5.0 (Windows NT 10.0; rv:91.0) Gecko/20100101 Firefox/91.0
Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Firefox/91.0
Mozilla/5.0 (X11; Linux x86_64; rv:90.0) Gecko/20100101 Firefox/90.0
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36 Edg/92.0.902.62
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36 Edg/92.0.902.73
Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:91.0) Gecko/20100101 Firefox/91.0
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36 Edg/92.0.902.55
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36 Edg/92.0.902.78
Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.164 Safari/537.36
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36
Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36
Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36
Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36 OPR/78.0.4093.147
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.164 Safari/537.36 OPR/77.0.4054.277
Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.164 Safari/537.36
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.115 Safari/537.36
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.3 Safari/605.1.15
Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:78.0) Gecko/20100101 Firefox/78.0
Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1 Safari/605.1.15
Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36
Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.164 Safari/537.36
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.0 Safari/605.1.15
Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:90.0) Gecko/20100101 Firefox/90.0
Mozilla/5.0 (X11; Fedora; Linux x86_64; rv:90.0) Gecko/20100101 Firefox/90.0
Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36
Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:89.0) Gecko/20100101 Firefox/89.0
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Safari/605.1.15
Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36
Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:91.0) Gecko/20100101 Firefox/91.0
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.1 Safari/605.1.15
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.164 Safari/537.36 OPR/77.0.4054.275
Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36
Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:78.0) Gecko/20100101 Firefox/78.0
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1.3 Safari/605.1.15
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1.2 Safari/605.1.15
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Safari/605.1.15
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36
Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36
Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:89.0) Gecko/20100101 Firefox/89.0
]]>