Part V - The Ultimate Linux Home Router - Services: SSH, Squid, Privoxy - Advertisement Blocking Network Wide

Saturday, December 21, 2013

Secure Shell Server (SSH)

A Secure Shell server is a great utility to have accessible externally. At home, I use port forwarding through my SSH server for a variety of uses. On public Wi-Fi networks, I fire up my SSH client on my phone and setup my browser to use my home proxy so that I can surf encrypted on a public network. When I'm visiting my children's school, I use the secure shell server to bypass the exceptionally restrictive firewalls installed at US public schools (and not for evil things ... simple things like Facebook don't work!). By opening one port to SSH, I am able to access my entire home network and all of its services. I can remote into my desktop or laptop via RDP. I can issue commands to my Roku. I can copy files (using WinSCP) to and from the public or family PC I'm working on to any PC on my home network.

Securing Secure Shell

Running a Secure Shell server doesn't come without risks. It's a high value target for hackers. Brute force attacks are extremely common, and are even done in ways that reduce the probability of detection (such as very slowly trying multiple common passwords). I allow password authentication for Secure Shell and am not providing steps on eliminating that (because I simply don't care enough about it). I strongly recommend using a very complex passphrase (multiple words, punctuation, with numbers mixed in) to ensure a brute force attack is unsuccessful.

Reducing attack surface of SSH

We're going to do the following: Pick a non-standard port for SSH. You have two options, each with pros and cons:
  • Option 1 - Pick a common port, such as Port 80 or 443. This will not reduce your attack surface that much, since these ports are also commonly attacked, but since SSH will be running on that port and not the service the hacking tool is looking for, it may render the tool ineffective (probably not). The pros of picking a common port like 80 or 443 is that they're unlikely to be blocked egress on a firewall. Pick a common port if the most important thing to you is being able to access your SSH server from anywhere.
  • Option 2 - Pick an uncommon, random port like 3154 (well, don't use that now that I put it in this post ... actually, it probably won't matter, the traffic to this site is pretty miniscule).
I chose option 2 because, lately, I've rarely ran into a scenario where I couldn't access a random port egress on even Public School WiFi.
We're going to eliminate root logon. Allowing root login is a very bad idea. This ensures that the attacker needs to not only guess the password, but also the ID in order to log into your server.
Run the following:
$ sudo nano /etc/ssh/sshd_config
#Port 22
#PermitRootLogin yes
#MaxAuthTries 6
Port xxxx
PermitRootLogin no
MaxAuthTries 1
Where xxxx is the number of the port you selected above. Save and Exit.
Run the following:
$ sudo nano -w /etc/sysconfig/SuSEfirewall2.d/services/sshd
Change TCP="22" to TCP="XXXX" where XXXX is the port you selected above, then run:
$ sudo rcsshd restart
$ sudo rcSuSEfirewall2 restart
Replace xxxx with the port you selected above.

Reducing attack surface with DenyHosts

Denyhosts is a script that trolls the logs looking for authentication failures. When it finds a certain threashold of them from a particular host, it adds that host to the hosts.deny file which prevents the server from accepting connections from that host in the future. We're going to set the threshold pretty low, so you may end up locking yourself out by accident. If that happens, simply login from a different host and remove the host from hosts.deny.
$ sudo zypper ar --refresh 'openSUSE 13.1 Network Utilities'
$ sudo zypper in denyhosts
(be sure to answer "a" when prompted)
$ sudo chkconfig --level 3 denyhosts on
Worthy Note: Because DenyHosts is running on your router, having too many login failures on a machine within your network will not only block you from logging in with SSH, it'll block you from connecting to anything (including the internet). So login with caution!

Proxy Servers

I'm debating, for the time being, precisely which proxy to install. I've used Squid for years, but there are alternatives out there and, in fact, we're going to be using one of them -- privoxy. There's no reason they all can't coexist on the same machine, however, it may not be necessary to run more than one. We'll chain squid and privoxy together and later, when we want to child-proof certain things on our network, we'll add squidGuard to the mix.
Run the following:
$ su
(enter your password)
# zypper in squid privoxy privoxy-doc
# systemctl enable squid
# systemctl enable privoxy
# nano /etc/squid/squid.conf
http_port 3128
http_port 3128 transparent
# nano /etc/sysconfig/SuSEfirewall2
Hit CTRL+W and type "FW_REDIRECT" to get to the line.
# rcsquid start
# rcSuSEfirewall2 restart
Browse to something on the internet on Port 80 within your local network and you can "cat /var/log/squid/access.log" to see that the proxy is working properly. Once you're sure that's up and solid, we'll chain privoxy.

Configuring Privoxy for Advertisement blocking for your whole network

I won't get into the ethical arguments around blocking ads. I would love to trust publishers to give me advertisements that weren't filled with malware, but at present, I can't. It pains me even more that the two or three affiliate links I may use on this site won't work after you follow these instructions, but I won't be a hypocrite and complain about that. Here's a longer discussion on the subject This is why I adblock and you should too. If you feel evil doing this, you can simply skip this section. This is one of a few methods we're going to use to eliminate ads on our network. This will also reduce the ability of web sites to track your behavior. Occasionally, privoxy gets it wrong and blocks something useful, but I've been running it for months now and it works brilliantly. There are some things as of this writing that are broken about the privoxy package provided in the 13.1/Tumbleweed repositories. We're going to tweak the service definition and load the service to correct this. First we'll modify the configuration:
# nano /etc/privoxy/config
Locate the following lines (hint: CTRL+W)
logdir /log
confdir /etc
Replace them with:
logdir /var/lib/privoxy/log
confdir /etc/privoxy
Locate the following lines:
#debug 4096
#debug 8192
Replace it with:
debug 4096
debug 8192
# nano /usr/lib/systemd/system/privoxy.service
Remove all lines in that file and replace it with:
Description=Privoxy Web Proxy With Advanced Filtering Capabilities

ExecStart=/usr/sbin/privoxy --user privoxy --pidfile /var/run/ /etc/privoxy/config
ExecReload=/bin/kill -USR1 $MAINPID

Run the following commands
# systemctl daemon-reload
# systemctl start privoxy

Chaining Squid and Privoxy

Run the following commands:
# echo 'cache_peer parent 8118 7 no-query' >> /etc/squid/squid.conf
(configures privoxy as a parent to squid)
# echo 'acl ftp proto FTP' >> /etc/squid/squid.conf
# echo 'always_direct allow ftp' >> /etc/squid/squid.conf
(skips privoxy for FTP requests)
# echo 'never_direct allow all' >> /etc/squid/squid.conf
(uses privoxy for all other requests)
# squid -k reconfigure
To test, simply fire up a browser that doesn't have Adblock installed and visit a page (non-SSL) that has lots of ads. You'll also notice some of the ads are gone from your phone as well.

Blocking Ads via BIND DNS

As I mentioned earlier, privoxy is not fool proof. It does land itself into false positives from time to time. While putting this together, I discovered one of those cases. We'll need to get some files from a site for our BIND DNS blocking, but in order to do that, we have to first configure privoxy to whitelist the site.
# echo "{ -block }" >> /var/lib/privoxy/etc/default.action
# echo "" >> /var/lib/privoxy/etc/default.action
In a browser somewhere on your network, click this link and make sure it's not blocked. Then run the following commands:
# nano /usr/sbin/
Paste the following:
wget ';showintro=0' -O /etc/
cat /etc/ | egrep '^zone' > /etc/
rcnamed restart
Save and exit, then run:
# chmod 750 /usr/sbin/
# ln -s /usr/sbin/ /etc/cron.daily/


Corrected DNS ad blocking section. Added cron job for downloading DNS list.

No comments :