Enable Wake on LAN on Windows 10

To be able to wake up your computer via wake-up-on-lan (WOL), you need to enable this feature in the BIOS and in the Windows 10 LAN adaptor settings.

Configuration: BIOS

Configuration depends on the BIOS of your computer. In my case, wake up on LAN is in the power on section and disabled by default. To use this feature, just enable it.

Do not forget to save the change.

Configuration: Windows 10

After activating WOL in the BIOS, you need to configure Windows 10 to allow the device to wake Windows. My test computer is a Lenovo Q180 running Windows 10 German. More information on how to activate WOL for this device can be found here.

Go to Network and adaptor properties. Select the LAN adaptor and open its properties. In the property screen, select Configuration.

Go the Entergy settings. Check all check boxes.

Now go to the next tab: Advanced. Ensure that Wake on Magic Packet is set to Enabled.

Windows Firewall configuration

To know that a computer is running, you can use ping. If the computer responses to a ping, it’s up and running. To allow ping requests through the standard Windows firewall, ensure that the rule for file and print service is activated for your network.

There are two network types: private and public. Activating ping for the private network should be sufficient. If you are unsure if your LAN is part of private or public, you can activate ping requests for both. At least, when your network is still secured by a router with firewall.

Block access from country by IP in Apache

In this blog I will show how you can block access to your Apache hosted internet services, forbidding access to a whole country. The access is blocked based on the IP address of a client. In case of a VPN where the user connects to a VPN server in another country, the user will still be able to access the site.

The internet is a great to ensure freedom of speech. Anyone can raise his/her voice; use the information to be informed on what is happening in the world, let others know about something, share knowledge. You can do so by using a social site or by hosting your own site. The ease of access to information; be able to search it instantly; have huge amount of information able to be discovered by a large number of the world population. This is one of the true great contributions to really make the world a better place. Some countries don’t like this, applying censorship, access restriction, or worse. And basically, if you decide to block a country to access your site, it’s one step to the wrong direction.

Why would you block a whole country? Isn’t a great thing about the internet that it’s accessible from anywhere in the world, just using a browser? It’s not as simple. A few reasons to block a country can be:

  • Legal requirements. Your site is not in compliance with the countries law. For instance, maybe you are logging too much personal information?
  • The functionality is not meant for that country. You have a commercial service, and are not offering a payment option or a localized version.
  • You are popular in a country and flooded with a lot of requests, but these are just operational overhead for you as your site is not targeted for these users.
  • If you think hard enough, you can come up with a good reason.

After finding yourself in the situation to block a specific country, the question is: HOW? You can use a blocker in your web platform (WordPress plugin), or use Apache to do so. Using a .htpasswd file for this is not optimal due to performance. Better is to use a module. A quick Google search reveals that a good option is to use the GeoLite DB from MaxMind. And they also offer an Apache 2.4 module. The module works with Apache 2 and the HTTPD server available on Amazon AMI images.

Some references to projects used to set the country blocking up.

Steps

Steps for using GeoLite2 DB for blocking countries in Apache

  1. Download GeoLite 2 DB
  2. Install dependencies
  3. Install Apache module
  4. Configuration
  5. Activation

1. Download GeoLite2 database

The GeoLite2 DB is available as a free and commercial license. The free version should be good enough for a private blog. You can get the free version from MaxMind site.

Select GeoLite 2 Country and binary format. Download the file using wget.

wget http://geolite.maxmind.com/download/geoip/database/GeoLite2-Country.tar.gz

Unzip the file.

tar zxvf GeoLite2-Country.tar.gz

The actual DB file is close to 3 MB in size.

Copy it to a directory were the apache users can find it. A good default location is /usr/local/share in a new directory named GeoIP.

sudo mkdir /usr/local/share/GeoIP
sudo cp /home/ec2-user/geolite2db/GeoLite2-Country_20170704/GeoLite2-Country.mmdb /usr/local/share/GeoIP/

2. Install dependencies

Install libmaxmind

For the Apache module to work, the C library libmaxmind must be installed. This can be done by using yum.

sudo yum install libmaxminddb.x86_64 libmaxminddb-devel.x86_64

HTTPD devel files

Another dependency is the HTTP development files. These can also easily installed using yum.

sudo yum install httpd24-devel.x86_64

3. Install Apache module

The Apache module is available as source code from GitHub. For installation, download the latest release from GitHub. In my case, the latest release was version 1.1.0. Download the tar file.

Download the release to Linux using wgetand unzip it.

wget https://github.com/maxmind/mod_maxminddb/releases/download/1.1.0/mod_maxminddb-1.1.0.tar.gz
tar zxvf mod_maxminddb-1.1.0.tar.gz

Now you can compile and install the module. To do so, run

./configure
sudo make install

This should compile and put the files correctly into the right directory of HTTPD. If an error occurs during configuration, compilation or installation, look at the error message and good luck.

The directive to load the new module was automatically added to the file /etc/httpd/conf/httpd.conf

To test that the module can be loaded, restart HTTPD.

sudo service httpd restart

The service needs to start without error. This indicates that the module was successfully loaded. To validate this, check if the new module is actually loaded by HTTPD. To do so, list all loaded modules.

sudo httpd –M

Search for the maxmind module:

maxminddb_module (shared)

The new module is correctly loaded by HTTPD. Now we can configure Apache to make use of the module.

4. Configuration

Edit the HTTP config file and add the directive to block a specific country. The GitHub site of MaxMind contains an example that serves as a very good starting point.

MaxMindDBEnable On
MaxMindDBFile DB /usr/local/share/GeoIP/GeoLite2-Country.mmdb
MaxMindDBEnv MM_COUNTRY_CODE DB/country/iso_code
SetEnvIf MM_COUNTRY_CODE ^(RU|DE|FR) BlockCountry
Deny from env=BlockCountry

Using the above example, let’s adjust it to block Brazil. No worry, I won’t block Brazil, this is just a test as my IP currently is from Brazil, making it easier for me to test the setup. To block Brazil, check if MM_COUNTRY_CODE starts with BR: SetEnvIf MM_COUNTRY_CODE ^(BR) BlockCountry

MaxMindDBEnable On
MaxMindDBFile DB /usr/local/share/GeoIP/GeoLite2-Country.mmdb
MaxMindDBEnv MM_COUNTRY_CODE DB/country/iso_code
SetEnvIf MM_COUNTRY_CODE ^(BR) BlockCountry
Deny from env=BlockCountry

Add the above configuration snippet into a Location or Directory directive. This is because of the Deny command. This cannot be added directly under a virtual host.

<VirtualHost _default_:443>
  <Location />
    MaxMindDBEnable On
    MaxMindDBFile DB /usr/local/share/GeoIP/GeoLite2-Country.mmdb
    MaxMindDBEnv MM_COUNTRY_CODE DB/country/iso_code
    SetEnvIf MM_COUNTRY_CODE ^(BR) BlockCountry
    Order deny,allow
    Allow from al1
    Deny from env=BlockCountry
  </Location>
</VirtualHost>

5. Activation

To activate the configuration and to block Brazil, a restart of HTTPD is needed.

sudo service httpd restart

After HTTPD is successfully restarted, the new configuration is activated. To see if it is working, a basic test is to just access the site from an IP address that is blocked.

Test

My IP is from Brazil, accessing my site now should give me an access denied message.

It works!

Convert SVG to PDF

Some time ago I registered for a virtual training. The training material was made available in a web app. No PDF or a downloadable version of the material. Not a big issue, as long as I had internet access and only wanted to read the material. Problems started when I tried to access the material without a stable Internet connection. Depending where I am online is not an option. Plus point for having training material in PDF format. I can print PDF, making it easier to learn: offline, annotate pages, mark words, easier to read for the eyes. While a cloud solution is good for the vendor, it’s not always a very good option for the consumer.

Taking a closer look I found out that the material was loaded by the web app as SVG files. All pages where available as SVG: page1.svg to pageX.svg. So I could save the SVG files to my computer. Not something feasible for all content, but for selected chapters or pages this can make sense. Now I wanted to have these SVG files as PDF. It’s possible to transform SVG to PDF, especially on Linux. The most used tools available are

  • convert
  • Inkscape
  • rsvg-convert

The challenge was to convert the files to PDF in an acceptable quality. All tools transform SVG to PDF, but the quality differs, and most important: how the images are included. The only tool that rendered the embedded images correctly in the PDF was rsvg-convert. A sample of a page that shows perfectly the problem with the image is this one. The SVG as shown in the browser:

Font is clear and easy to read, the image in correctly embedded and shows all content. Now I wanted to have this page in PDF, with the exact same information included and in a good quality. For this, I tried all three tools and compared the result. All tools were installed and tested in Raspbian.

Convert

Convert is part of Image Magick. To get the tool under Debian you must install imagemagick.

Installation

apt-get install imagemagick

Run

convert page1.svg page1.pdf

Result

After the conversion from SVG to PDF, the result was far away from being useful. The font is not sharp, low quality, and the image is only showing half of the content. I think it’s possible to increase the quality of the font, but that the image isn’t correctly shown is a no-go.

Inkscape

Inkscape is an image editor, and comes with a GUI for end users. But there is a command line option available that can be used to transform a SVG to PDF.

Installation

sudo apt-get install inkscape

Run

inkscape page1.svg --export-area-page --without-gui --export-pdf=page1.pdf

Result

The quality of the font is better. Easy to read, sharp and clear. The image however is still not complete. This disqualifies Inkscape also as an acceptable solution.

rsvg-convert

This tool is part of librsvg. It comes from Gnome and has some “heavy” dependencies. The tool can convert SVG files to images like PNG or PDF.

Installation

sudo apt-get install librsvg2-bin

Run

rsvg-convert -f pdf -o page1.pdf page1.svg

Result

The quality of the font is good, easy to read and clear. The image is correctly shown. Definitely the best solution.

Conclusion

A lot of tools are available to convert SVG files to PDF. I did not even mention libraries available for Java or Javascript to do the job. The difference between the tools is how more complex SVG files are converted into PDF and if all information is included. Especially images can be a challenge for the tools. Based on my tests, I can recommend rsvg-convert. It is fast and gives a very good result.

Install SAP Web Dispatcher on Docker using SWMP

SAP Web Dispatcher is an important component in a SAP landscape. While have been treated as optional for many years and found mainly in SAP Portal scenarios, with the increase adoption of Fiori, having a reverse proxy in the landscape is becoming pre-requisite. While it’s possible to choose from a wide range of alternatives of servers for a reverse proxy, SAP`s Web Dispatcher is normally always the best fit in a SAP landscape. A question that sometimes arises is how to install Web Dispatcher.

First you settle on what version of Web Dispatcher (WD) to install. SAP Note 908097 states that you should go for the latest version. “Version 7.49 is the recommended SAP Web Dispatcher version for all backend systems.”

The actual installation gives you two options:

  • easy and
  • recommended.

The easy alternative is to simply un-sapcar the WD SAR file downloaded from Service Marketplace into a directory. To run WD, it`s then just to bootstrap it or run it with a given profile file. This installation method gives you a up and running WD in just one minute. The problem is that the files are all in one directory and not in the “official” directory structure of a normal SAP installation. But you get something like a portable WD installation: zip the directory and you can copy it to another server and can run WD from there.

The recommended alternative ensures that the WD is installed like a normal SAP product: all files follow the normal directory structure, etc. Installation is done using SWPM. Important when you are going to do some advanced configuration like PSE encryption, CryptoLib installation, etc. I`ll try to show how to install SAP Web Dispatcher the recommended way.

Download software

Download the needed software. It`s SWPM, Web Dispatcher, SAPCAR and HOSTAGENT.

SWPM

SAP Web Dispatcher 7.49 PL 112

SAPCAR 7.21

SAP Host Agent 7.21

Result

After you have downloaded all software, you have four files, summing up to almost 900 MB.

In a Unix environment, your WD system won`t have a graphical user interface and access to the system is given by SSH. This kind of environment can perfectly be emulated using Docker. Note: the SAR files need to be copied over to the target host.

Docker

There are several Linux images available for Docker. Let`s use Debian for this.

docker pull debian

For the actual image, see my Docker setup for Web Dispatcher: Dockerfile and docker-compose.yml: https://github.com/tobiashofmann/docker_webdispatcher_swpm

After running the Docker image, you have the files on the Linux system up and running, the Web Dispatcher and sapinst files available. Web Dispatcher is not yet installed. This is done by using sapinst. To run the installation, you`ll have to connect to sapinst using a different computer (most cases: your laptop). Let`s call the Docker container the target, and your computer the client.

Logon

I use Kitematic and to log on to my docker container, I just click on the EXEC button.

Logon to Docker container:

The log on from shell, the command is something like this:

bash -c "clear && docker exec -it dockerwebdispatcher_web_1 sh"

Target

To work properly, sapinst must be started as root. You then connect to it and log on. The logon is done by default with the user id running sapinst. Problem is that with the Docker images you do not know the root password. Same for environments where root access is only provided to a few or via sudo. You need to enable sapinst to run as root, but allow a different user (like <sid>adm) to log on. You achieve this by providing a parameter to sapinst informing the OS user allowed to log on remotely. The process is then:

  • Run sapinst as root (or sudo)
  • Connect to it informing a OS user (wddadm)

Sapinst Parameters

The needed parameter can be retrieved by letting sapinst show all available parameters. More information available in SAP Note 1745524 and at SAPinst central note.

./sapinst –p

Run sapinst in Docker

Provide the <sid>adm user as a property to sapinst.

./sapinst --properties SAPINST_REMOTE_ACCESS_USER=wddadm -nogui

Confirm that you know what you are doing.

Client

Start sapinstgui and connect to the target server on port 21212.

./sapinstgui

Inform the host name or IP address. In my case, it is 192.168.0.16. The port is the default sapinst port 21212.

Accept the fingerprint. You can check the fingerprint with the one printed by sapinst on the target server to be extra sure you are connecting to the right server.

Authenticate. You`ll need to provide the user id and password of the user running sapinst on the target host. In my case, the user is wddadm with password whatever. This is defined in the Dockerfile when the user is created.

sapinst output in Docker:

Logon on using wddadm / whatever

After a successful logon, sapinst will start. Current setup is not supported by SAP. For a production case this is a no-go, for my personal use case this is totally acceptable.

Sapinst shows the list of installable software options available. Web Dispatcher can be found at the end of the list.

Selecting SAP Web Dispatcher will start the installation.

Inform the path on the target server where the SAR files for SAP Web Dispatcher and SAP Host Agent can be found.

The files were copied into the container during the execution of the Dockerfile. All files are located at /home/wddadm.

If all packages are found, validated and added as considered valid for the installation.

Debian in Docker for sure won`t pass all the pre-requirements check build into SWMP. You`ll get a warning message, but SWMP won`t stop the installation. Select No. Seems that inside Docker, checking for the available free space is not working correctly.

Web Dispatcher configuration

Bootstrapping

Don’t worry, the system must not be accessible, yet exist. It’s just informing the bootstrap parameters. In my case, I am using a system that is not available, and it worked. Just be aware that in case the backend system changes, or isn’t even a ABAP system, like SMP3, you need to configure the Web Dispatcher profile manually.

Confirmation

Installation

The last step is to start Web Dispatcher. You can follow this on the console log of sapinst on the target server

If all worked, you get a confirmation message and the installation finishes.

SAPinst on the client host ends and so does it on the target host.

Validate installation

This gives you the time to validate the installation and check if all files are correctly installed.

Users

A new user sapadm was created

Folders

Web Dispatcher is installed under /sapmnt and instance is found in folder /usr/sap

This is perfectly aligned with the default locations of a SAP instance, and way better than simply putting all files into the same folder when unzipping the SAR. Especially when you consider that you may have to open a CSS ticket to SAP in your production environment or have new consultants arriving that expect the files to be located at the default location.

SAP Host Agent

The host agent was started and is running.

Start and stop Web Dispatcher

Starting and stopping Web Dispatcher via stopsap and startsap is working

stopsap

startsap

Admin web interface

The admin port of Web Dispatcher is listening by default on port 44300.

To access the service, the URL is

https://localhost:44300/sap/wdisp/admin/public/default.html

Log on to Web Dispatcher using the user webadm and password informed during installation.

Parallel download of files using curl

In a previous blog, I showed how to download files using wget. The interesting part of this blog was to pass the authentication cookies to the server as well as using the file name given by the Content-Disposition directive when saving the file. The example of the previous blog was to download a single file. What if you want to download several files from a server? Maybe hundreds or even thousands of files? wget is not able to read the location from a file and download these in parallel, neither is curl capable of doing so. You can start the download as a sequence, letting wget/curl download the files one by one, as shown in my other blog. Just use a FOR loop until you reach the end.

Commands

For downloading a large amount of files in parallel, you`ll have to start the download command several times in parallel. To achieve this, several programs in bash must be combined.

Create the list of files to download. This is the same as shown in my previous blog.

for i in 1 {1..100}; do `printf "echo https://server.fqdn/path/to/files/%0*d/E" 7 $i` >> urls.txt; done

Start the parallel download of files. Start 10 threads of curl in background. This is an enhanced version of the curl download command of my previous blog. Xargs is used to run several instances of curl.

nohup cat urls.txt | xargs -P 10 -n 1 curl -O -J -H "$(cat headers.txt)" >nohup.out 2>&1 &

Explanation

The first command is creating a list of files to download and stores them in the file urls.txt.

The second command is more complex. First, cat is printing the content of urls.txt to standard-out. Then, xargs is reading from standard-in and uses it as input for the curl command. For authentication and other headers, the content of the file headers.txt is used. The input for curl for the first line is then:

curl -O -J -H "$(cat headers.txt)" https://server.fqdn/path/to/files/0000001/E

The parameter –P 10 informs xargs to run the command 10 times in parallel. It takes the first 10 lines of input and starts for each input a new curl process. Therefore, 10 processes of curl are running in parallel. To run more downloads in parallel, give a higher value for –P, like 20, or 40.

To run the download in background, nohup is used. All output is redirected to nohup.out: >nohup.out 2>&1

SSH

To have the download running while being logged on via SSH, the tool screen should be used. After logon via ssh, call screen, run the above command, and hit CTRL + A + D to exit screen.

ssh user@server.fqdn
screen
nohup cat urls.txt | xargs -P 10 -n 1 curl -O -J -H "$(cat headers.txt)" >nohup.out 2>&1 &
CTRL+A+D
exit

Download files with leading zero in name using wget

In my previous blog I showed how wget can be used to download a file from a server using HTTP headers for authentication and how to use Content-Disposition directive send by the server to determine the correct file name. With the information of the blog it`s possible to download a single file from a server. But what if you must download several files? Maybe hundreds or thousands of files? Files whose file name is created using a mask, adding leading zeros?

Add leading zeros

What you need is a list of files to download. I`ll follow my example from the previous post and my files follow a specific patter: number. All files are numbered from 1 to n. To make it more special / complicated, it`s not only 1 to n. A mask is applied: 7 digits in total, with leading 0. 123 is 0000123, or 5301 is 0005301. In recent versions of Bash, you can use a FOR loop to loop through the numbers and printf for formatting the output and add the leading zeros. To get the numbers correctly formatted, the command is:

for i in 140000 {140001..140005}; 
  do echo `printf "%0*d" 7 $i`; 
done

This prints (echo) the numbers 140000 to 140005 with leading zero.

Start download

Adding the wget command in the printf directive allows to download the files. The execution flow is to let the FOR loop together with printf create the right number with mask, and wget downloads the file. After the file is download, the next iteration of the FOR loop starts, and the next file is downloaded. Assuming that I have PDF documents named 0140000.pdf to 0140005.pdf on server http://localhost:9080, the FOR loop with wget is:

for i in 140000 {140001..140005}; 
  do `printf "wget -nc --content-disposition http://localhost:9080/%0*d.pdf\n" 7 $i`; 
done

Result

Alternative

The above example is using wget. Of course, you can do the same using curl.

SAPInst error java.net.InetAddress.getHostAddress

SAPinst is used to install SAP software. You can run the installation with its graphical user interface (GUI) directly on the target host, or use a remote installation. Remote installation is normally used when the target host offers no GUI and all work is done via remote logon, like SSH. In such a setup, on the target host sapinst is started in server mode, and on the admin laptop, sapinst is started in with a GUI. The admin then connects to the target and executes the installation of SAP software remotely.

Error: java.net.InetAddress.getHostAddress

The setup to reproduce the error is to have sapinst running on a target host and listening on the default port 21212 and connecting to this instance using sapinstgui.

Setup target host

Start sapinst on the target host:

./sapinst -nogui

Setup client host

Start sapinst in GUI mode: ./sapinstgui Inform the target host (computername or IP)

Accept the fingerprint.

Error

Sapinstgui hangs and is not advancing to the next screen. The status bar shows that it`s connected:

On the target server, sapinst gives this error message:

java.lang.NullPointerException: while trying to invoke the method java.net.InetAddress.getHostAddress() of a null object loaded from field com.sap.sdt.util.misc.Uid.address of an object loaded from local variable 'this'

Solution

To solve this error, a configuration on the client computer is needed. While not obvious, the error is caused by a misconfiguration of the client DNS resolution. Easiest solution is to manually change the hosts file and to ensure that the client computer name is listed. To find out the computers host name, run hostname.

hostname

In my case, the host name is linux-01sn.

Example: wrong hosts file

The host name is not listed in the hosts file. To correct this, insert the hostname for instance to localhost.

Example: working hosts file

Test

To see if sapinstgui can now connect to the target server without error, restart sapinstgui. After connecting to sapinst server, you`ll get the authentication screen.

sapinst output on target host:

Custom 503 error page for Apache

A 5xx error code is returned by a web server when something went wrong: The server was not able to process the request. For a reverse proxy, a common 5xx error message is 503, meaning that the backend server is not reachable.

In the technical architecture of my blog site, the WordPress site with my blogs is hosted on a Raspberry Pi in my living room, while external access is through a reverse proxy hosted on Amazon EC2. If now the reverse proxy on EC2 cannot reach my Raspberry Pi, a 503 error message is given.

The root cause can be that the Raspberry Pi is turned off, there is no Internet connection available for some reason (power outage, provider problem), or something else. In case this happens, EC2 reverse proxy will throw an error and try to show the Apache standard 503 error page. The web page used to display the 503 is the same for all Apache installations worldwide. Giving your users a more personalized message can be a nice touch. For instance, including a statement that you are aware of the issue, it won`t take long to get solved, or a better explanation of what happened.

For this to work, you need to have

  1. A custom 503.html file and
  2. Configure Apache to use this web page.

Create custom 503 file

This is up to you. Internet and Google are your friend.

Apache configuration

Apache has the ErrorDocument directive. For an HTTP error code you specify a HTML file to be shown. Make the 503 HTML file created by you in the above section available on the web server.

/var/www/html/error/503.html

Important: the document root of Apache is /var/www/html. For accessing the file, the browser will call the URL /error/503.html. Reference it in the Apache configuration.

sudo vim /etc/httpd/conf/httpd.conf

Insert

ErrorDocument 503 /error/503.html

You are done in the case of a normal web server setup. The configuration shown so fare won`t work for a reverse proxy. A reverse proxy will forward all requests to the backend server, including the request for the 503 document. To not forward /error/503.html to the backend, put /error/ in a exception list. With this, every request to /error/ won`t be forwarded by Apache, and instead be served from the local web server. To exclude /error/ from the ProxyPass rule, add:

ProxyPass /error/ !

This exclusion must be before the other ProxyPass directives. A somewhat more complete example of a Apache configuration:

<VirtualHost _default_:443>
  DocumentRoot "/var/www/html"
  ProxyPass /error/ ! 
  ErrorDocument 503 /error/503.html
  SSLProxyEngine On
  ProxyPass / https://backend/
  ProxyPassReverse / https://backend/
  SSLEngine on
</VirtualHost>

Restart Apache

sudo service httpd restart

The next time the backend server is not reachable, the reverse proxy will serve the custom 503 error page to the users.

Download files with wget

A tool for download web resources is wget. It comes with a feature to mirror web sites, but you can also use it to download specific files, like PDFs. This is very easy and straightforward to do:

wget <url>
Example: wget http://localhost/doc.pdf

This will instruct wget to download the file doc.pdf from localhost and save it as doc.pdf. It is not as easy when the weber service is

  • requesting authentication or
  • the URL of the PDF file ends in the same file name

Authentication

The documentation of wget states that you can provide the username and password for BASIC authentication. What about a web site that asks for SAML 2.0? You can pass HTTP headers to wget via parameter –header. This feature makes it easy: log on to the server via a browser and then copy the headers. These headers contain the session information of you user and can be used by wget to connect as an authenticated user.

How to get the HTTP headers

  1. Log on to the web site
  2. Open developer tools
  3. Select a web resource
  4. Copy the HTTP headers. For cURL, its just selecting Copy all as cURL. This gives the complete cURL command. For just the headers, select Copy Request Headers.

Example:

User-Agent: Mozilla/5.0 Chrome/56
Accept-Encoding: gzip, deflate, sdch, br
Cookie: JSESSIONID=DBE1FED5C040B2DF7;

Each line is one –header parameter for wget. It is not feasible to add all these headers to each wget request individually. For maintenance and better readability these values should be read from a file. Problem: wget does not allow to read the header parameter from a file. There is no option for something like –header <file_with_headers>. What there is the . wgetrc file. This is the configuration file wget reads when called, and in this file it`s possible to define HTTP header values. For each HTTP header, create a new “header = <value>” entry in the file.

With this configured in the file, wget will send always these HTTP headers with each request. If the session cookies copied from the browser are valid the requests are authenticated and wget is able to download the file.

File name

Sometimes the file you want to download has a generic URL. Each file ends in the same file name at the server. For instance, http://localhost/category/doc.pdf, or /uid/E.pdf. In such cases, wget will download the file and save it as doc.pdf or E.pdf. This is not a problem when you download just one file, but when you download more files, like 20, wget numerate the files: E.pdf.1, E.pdf.2, E.pdf.3, …

This makes it hard to work with the files. A solution can be to check if the web server is supporting content-disposition. If so, the server should send the real file name of the archive in the HTTP response. The real file name can be seen in the Conent-Disposition header as filename.

With content-diposition, wget can save the downloaded file from /<UID>/E.pdf as <UID>.pdf instead of E.pdf. As the UID is unique, the file can easily be identified after download.

wget --content-disposition http://localhost/<uid>/E.pdf

Given the above example, the file download is saved locally as 2399104_E_20170304.pdf

A start job is running for dev-disk-by

Recently I restarted one of my Linux servers and the computer did not start up as expected. No external accessible service was running, like apache or SSH. This made the computer inaccessible from remote and left me in the dark. After a while, the server responded to ping, but nothing more.

After I connected the server to a display and keyboard, I could see the error message: “a start job is running for dev-disk-by […]”. After that, Linux gave me only the option to log on in rescue mode or to restart the system. A restart didn`t help. I checked the internet and found out that the message can be caused by a fstab entry.

Looking at the content of my /etc/fstab file I could see an old entry I once created for a test and never maintained (aka deleted). The system is trying to mount a partition that was not available / broken and the system stopped.

UUID=a6674495 -4249-9696-0d9c83 /mnt/disk btrfs defaults,noatime,auto 0 0

I commented out this line in fstab and restarted the system. Now the system was restarted correctly and all the services came up again.