Managing HTTP BASIC Authentication, in your Docker Apache container

Ref:
https://mrgood.blog/posts/2021-03-11-apache-auth/post.html
https://httpd.apache.org/docs/2.4/programs/htpasswd.html

I haven’t logged into a website using Basic Authentication + SSL in 20 years. It is a outdated technology, still available in Apache. All the modern websites use a technology like OAuth, whose basics for authentication is:
1. There is no standard for how the credentials are passed and this is entirely up to the organization. And this is why, OAuth always asks for a user and password, thru a custom web page. You can name the variable anyway you want, and the user has to be able to interpret what the organization is asking for, from the web browser rendering of the login box. And the programming in it, sends back the credentials in it’s custom method. It can change at any time. (But it doesn’t, but it can)
2. The credentials are only sent once, and once verified, a login token is sent back to browser, so this is the only thing that can be hijacked, if someone accesses the data stream or your computer after login. Not your username and password.

HTTP Basic Authentication is sooo outdated

it is considered dangerous. B/c Basic Authentication protocol repeatedly transmits the password in a easily decoded state. And people today are too un-educated to know the difference between protection by SSL encryption and protection by basic authentication.

That incompetent usage, is nearly the same as spoofed security.

Basic Authentication sends your password every request. And it doesn’t require the connection is SSL. But it is very very very easy to implement in both Apache and IIS.

IIS just need the IUSR_* user not to be assigned to the folder, and IIS will ask for basic authentication for a user that has permisssion to the NTFS folder. IUSR_* user is the guest user for IIS. If that user has read permission on the NTFS folder and it’s contents, IIS can serve the file (basic authentication needs to be enabled in the IIS Admin, and you can use NTLM auth too, in same way, with IE, god bless it’s deprecated soul). IIS is very integrated with Windows ecosystem. Apache, it is enabled in the .conf files. The user list using htaccess is completely different from the Linux login user database.

Here we will go over enabling Basic Auth in apache container. The file system is different from the Debian distrubution apt isntall locations. The good thing is htpasswd tool, reflects immediately, upon adding users to htpasswd. The process doesn’t need to be restarted

Why would you want to do this? Since it is a outmoded technology? Maybe you want to enable password access to a webpage, that you just need implemented fast, and you just want to use self-signed certificate. Or no one in your dept (unlikely) wants to sniff out someone else’s password to the web resource, bc it is such low priority, the work involved to sniff it and hide it, isn’t worth the trouble. Like maybe the vacation schddule.

First start apache container. Below we start it on, on port 8080 b/c it is very likely most people have port 80 used. But if you don’t, you can replace the 8080 with 80, and you don’t need to specify 8080 in your browser (b/c 80 is default, if you don’t specify it)

docker run -p 8080:80 -it --name apache2 httpd:latest

I renamed the container to “apache2” to make it easier to reference later.

Now goto a Web browser and enter the address

http://localhost:8080/

I get “It works!” b/c that is the default content provided by the Apache container. It is currently running, and serving files for a “guest” user or anyone.

I didn’t specify -d, which will run the container in background. So open another terminal window (leaving the container running in the other window).

To enable basic authentication, you need 4 files changed in the container’s file system
1. /usr/local/apache2/conf/httpd.conf
2. /usr/local/apache2/conf/extra/httpd-vhosts.conf
3. /usr/local/apache2/htdocs/.htaccess
4. /usr/local/apache2/.htpasswd

First. /usr/local/apache2/conf/httpd.conf

We need to enable the 2nd file to be activated

# Virtual hosts
# Include conf/extra/httpd-vhosts.conf

needs to be changed to

# Virtual hosts
Include conf/extra/httpd-vhosts.conf

Because nano is not installed on the container file system, it easiest way to change it, is copy it out, change it, and copy it back in.

docker cp apache2:/usr/local/apache2/conf/httpd.conf httpd.conf
nano httpd.conf
docker cp httpd.conf apache2:/usr/local/apache2/conf/httpd.conf 

2. /usr/local/apache2/conf/extra/httpd-vhosts.conf

You are adding a default Host, and saying it has a basic authentication activated, and the list of usernames and password for this folder is in “/usr/local/apache2/.htpasswd”

You need add the entry anywhere in the file “/usr/local/apache2/conf/extra/httpd-vhosts.conf”. Append to end is fine.

<VirtualHost _default_:80>
  DocumentRoot "/usr/local/apache2/htdocs"
  <Directory "/usr/local/apache2/htdocs">
    Options Indexes
    AuthType Basic
    AuthName "Restricted Content"
    AuthUserFile "/usr/local/apache2/.htpasswd"
    Require valid-user
  </Directory>
</VirtualHost>

Again, since nano is not installed in the container file system, the easiest way to change it, is copy it out, change it, and copy it back in.

docker cp apache2:/usr/local/apache2/conf/extra/httpd-vhosts.conf httpd-vhosts.conf
nano httpd-vhosts.conf
docker cp httpd-vhosts.conf apache2:/usr/local/apache2/conf/extra/httpd-vhosts.conf 

3. /usr/local/apache2/htdocs/.htaccess

For some reason, this file repeats what is in file #2

AuthType Basic
AuthName "Restricted Content"
AuthUserFile /usr/local/apache2/.htpasswd
Require valid-user

This file doesn’t exist in container, so just create it on the host, add the content above, then copy it back in container

nano htaccess
docker cp htaccess apache2:/usr/local/apache2/conf/extra/.htaccess 

4. /usr/local/apache2/.htpasswd

This file you will not create manually. You can look inside, after it is created. It creates the username and passwords for this site. But the utility needs to be installed and apt exists in the container to do this.

So the command creates a shell to container file system, installs the “htpasswd” utility, then executes it, which the utility creates specified “.htpasswd” in “/usr/local/apache2/” directory (which is where the configuration files above, say where apache expects the file) with the initial “admin” user and a random password generated from uuid. You will notice when the new “.htpasswd” file is displayed, that the password is encrypted/hashed.

docker exec -it apache2 bash
apt install apache2-utils
cd /usr/local/apache2/
htpasswd -c -B .htpasswd admin $(</proc/sys/kernel/random/uuid)
cat .htpasswd

Remember to exit the container shell

Now the initial configuration is all done, but nothing has taken hold, b/c apache2 web server needs to be restarted, to enable the basic authentication configuration. And now we have finished that. So now we restart apache web server.

I didn’t give the -d in “docker run -p 8080:80 -it –name apache2 httpd:latest”, so you are probably viewing the logs being output. And you will see a successful access to “/” with status 200. You can exit this, and run:

docker restart apache2

It will restart in background, but you can see log:

docker logs apache2

Go back to the Web browser and refresh

http://localhost:8080/

and it should ask for a username and password. Run the log command again. You should now get a code 401 at end (where before it said 200). 401 means the apache server expected the username/password to be sent, that matches a user/password in it’s database, and one wasn’t sent.

192.168.1.100 - - [date] "GET / HTTP/1.1" 401 len

A similar error appears in log, for wrong password:

192.168.1.100 - entereduser [date] "GET / HTTP/1.1" 401 len

You can enter the “admin” and the password, but you don’t know it. The command I gave you, gave it a random password, that it didn’t display to you. So I could force you to run another command, to add a user with a password you know.

You will use the same “htpasswd” utility to create the file. You can create a shell to the container (bash), but the command below executes the command “htpasswd -b -B .htpasswd tempuser temppassword” in the container directly.

docker exec -w /usr/local/apache2/ -it htpasswd -b -B .htpasswd tempuser temppassword

which creates a user “tempuser” with password “temppassword” in the file “/usr/local/apache2/.htpasswd”.

Go back to the Web browser and enter the username/password “tempuser” “temppassword”

http://localhost:8080/

It should show the “It works” again.

And run the logs again, and now you see:

192.168.1.100 - tempuser [date] "GET / HTTP/1.1" 200 45

the user means this was what was sent by the browser, and 200 means the right password was sent.

Notice I didn’t ask you to restart apache2. Unlike the .conf files, the “.htpasswd” file changes don’t require a restart of the container. So you can add and remove users, and it will reflect immediately. For instance, let’s remove the user. The important command to remove the user is bolded, the rest is to tell it what container (and directory) to run the command in

docker exec -w /usr/local/apache2/ -it htpasswd -D .htpasswd tempuser

Go back to the Web browser that had the username password entered that worked, and refresh. it should now ask for username/password again, b/c the one sent, no longer matches what is in the “.htpasswd” file:

http://localhost:8080/

Good luck. This is just if you want EASY way to add username and password access to a web resource. It is a outdated method by now. Look up OAuth, if you want to see how to implement the modern implementation of authentication. But it should be more complicated, if indeed it implements the benefits I stated about it, above.

For those of you who want to know why I am using something outdated

I’m using basic authentication to implement a one time username/password system. So I can add and remove them, as they are temporarily valid. It is probably how I’d implement OAuth tokens to my resource.

Basic Authentication is easy to implement, despite its drawbacks.

Leave a Reply

Your email address will not be published. Required fields are marked *