$ sudo apt-get install sasl2-binThe installation creates a "sasl" group, to which all users who want to use the authentication, must belong, so add yourself:
$ sudo adduser LOGIN saslLog out and back in to pick up the group change. Look for "sasl" mentioned here:
$ groupsEdit the file /etc/default/saslauthd and look for the line:
START=noand change it to:
START=yesStart the SASL service:
$ sudo /etc/init.d/saslauthd startTo test SASL's effectiveness run this (beware that your password is not hidden!)
$ testsaslauthd -u LOGIN -p password-for-LOGIN
0: OK "Success"
$ clear
$ history -c (OK, I'm paranoid)
$ sudo apt-get install libapache2-mod-authn-sasl $ sudo a2enmod authn_saslLike you, Apache's user must belong to the sasl group:
$ sudo adduser www-data saslThen restart (not reload) Apache:
$ sudo /etc/init.d/apache2 restartWe're going to show how to protect a specific directory of your web space, ~/public_html/protected. Create the directory and create an empty file within:
$ mkdir ~/public_html/protected $ touch ~/public_html/protected/empty.htmlThen edit the configuration file, /etc/apache2/conf.d/admin.conf, which you used to assign yourself greater Apache priviledges in the Apache + Blog document. Add this content at the end of the file:
<Directory /home/LOGIN/public_html/protected> AuthType Basic AuthName "Restricted" AuthBasicProvider sasl AuthBasicAuthoritative On AuthSaslPwcheckMethod saslauthd Require user LOGIN </Directory>Then reload Apache:
$ sudo /etc/init.d/apache2 reloadIf you do a web directory listing: The protected directory. is hidden until access is authenticated. Go in: It's looking for your login and your password (the password is hidden). Going back to reveals the protected directory in the listing.
Create a shell-less user, user1:
$ sudo adduser --no-create-home --shell /bin/false user1The adduser command prompts for account information. You have to give it a password, let's say "user1foo"; other that that you can ignore the remaining fields by hitting Enter. When you're done, see what happened by compare to your login to user1's login:
$ egrep "^(user1|LOGIN):" /etc/passwdYou'll see that user1 is harmless because it is has no shell login and owns no files on the system. Then, modify /etc/apache/conf.d/admin.conf by changing the line:
Require user LOGINto one of these two alternatives:
Require user LOGIN user1or
Require valid-userReload Apache:
$ sudo /etc/init.d/apache2 reloadA test of the effectiveness would be this:
User: user1, Password: user1foo
User: LOGIN, Password: password-for-LOGINIn any case, we need only "give out" the login/password information for user1 to allow web access, and this permits no shell access.
~/public_html/protected/.htaccesswhich contains the current contents of directives above, minus the starting and ending Directory tags. The differences in these approaches are:
# cd /usr/local/etc # mkdir ssl # chmod 700 ssl # cd sslThe important operations are done by use the openssl operation. Executed without parameters, it functions as a command interpreter:
# openssl OpenSSL> ...Alternatively, you can execute openssl commands directly from the shell prefacing them with "openssl". The following sequence generates a private key, my.key, and a certificate request, my.csr:
OpenSSL> req -new -nodes -out my.csr -keyout my.key Generating a 1024 bit RSA private key ..............................................++++++ .++++++ writing new private key to 'my.key' ----- You are about to be asked to enter information that will be incorporated into your certificate request... ----- Country Name (2 letter code) [..]:US State or Province Name (full name) [..]:Pennsylvania Locality Name (eg, city) [..]:West Chester Organization Name (eg, company) [..]:WCU Organizational Unit Name (eg, section) [..]:Computer Science Common Name (.. your server's hostname) [..]: MACHINE.cs.wcupa.edu Email Address []:root@MACHINE.cs.wcupa.edu Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: (hit Enter) An optional company name []: (hit Enter) OpenSSL> quitLet's see what we've got:
# ls my.key my.csr # cat my.key # cat my.csrFor a real certificate, my.csr would be sent to a Certificate Authority for "signing". Instead, we'll sign it ourselves as follows:
# openssl OpenSSL> x509 -in my.csr -out my.crt -req -signkey my.key -days 9999 OpenSSL> quit # ls my.crt my.csr my.key # cat my.crtThe file my.crt is our self-signed certificate. The two files we need are my.key and my.crt. For extra security, make them read-only for root:
# chmod 600 my.*
$ sudo a2enmod ssl $ sudo a2ensite default-sslEdit the file /etc/apache2/sites-enabled/default-ssl. Look for the lines:
SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.keyand change the values to:
SSLCertificateFile /usr/local/etc/ssl/my.crt SSLCertificateKeyFile /usr/local/etc/ssl/my.keyRestart apache:
$ sudo /etc/init.d/apache2 restart
Preferences
Advanced
Encryption
View Certificates
Servers
<Directory /home/LOGIN/public_html/protected> SSLRequireSSL ... </Directory>
$ sudo a2enmod rewrite $ /etc/init.d/apache2 reloadAgain, edit /etc/apache2/conf.d/admin.conf and enter the following lines at the end: Keep SERVER_NAME literally as it is, do not replace it by your actual server's name. Be careful to use curly brackets in the %{..} expression.
# uncomment the RewriteLog.. lines to help debug rewrite rules.
# Never leave the RewriteLogLevel at "9" in a production system
# because it will negatively affect performance.
#RewriteLog /var/log/apache2/rewrite-log
#RewriteLogLevel 9
<Directory /home/LOGIN/public_html>
RewriteEngine on
RewriteCond %{HTTPS} off
RewriteCond %{REMOTE_ADDR} !^127\.0\.0\.
RewriteRule ^protected(/.*)?$ \
https://%{SERVER_NAME}/~LOGIN/protected$1 [R,L]
</Directory>
Afterwards, reload Apache and test out:
RewriteRule ^protected(/.*)?$ \
https://%{SERVER_NAME}/~LOGIN/protected$1 [R,L]
Let's say that we're accessing the URL:
http://MACHINE/~LOGIN/protected/empty.htmlis accessed these are in effect:
/home/LOGIN/public_html/protected/empty.htmlwithin Apache's
<Directory /home/LOGIN/public_html>This directory prefix is stripped off (including the terminating "/"), leaving the string "protected/empty.html" which matches the regular expression ^protected(/.*)?$. The string "/empty.html" matches the parenthesized portion. Accordingly, the match is successful, "/empty.html" becomes the value of the special match variable $1, %{SERVER_NAME} becomes MACHINE, yielding the rewrite rule's target:
https://MACHINE/~LOGIN/protected/empty.htmlThe [R,L] appended to the rule means: this is the Last rule to apply (if there were a sequence), and we should Redirect the browser to the target.
RewriteCond %{HTTPS} off
means "only proceed if we're not using https". Without this rule, we
would end up in an infinite rewrite sequence since the target is https.
The next one:
RewriteCond %{REMOTE_ADDR} !^127\.0\.0\.
means "only proceed if the client's IP address (i.e., %{REMOTE_ADDR}) does
not (!) match the regular expression ^127\.0\.0\."
The significance is that we do not want to activate
the rewrite
if our client is a local IP (represented by 127.0.0.something")
when the https would be unnecessary.