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.