Tuesday, 15 March 2022

AdGuard Home and time based rules

I have to say, I really like AdGuard Home (AGH)... and I am a bit torn between PiHole and AGH. PiHole seems to have better dashboard and allows to drill more into logs, but AGH has more features, so in a way it is horses for courses.

Recently a new use case came up for me - to block certain websites/services based on time of day. Think of it as technical layer of parental controls. I call it technical layer, because I know a conversation with a child is way more effective than any technical solution. At the same time kids being kids (even the most obedient and respectful ones) will sooner or later try to see if something is really blocked or is dad bluffing. Let them... it's good they try.

AGH API

AGH has a working API that is documented here. If you paste the contents of openapi.yaml into web based Swagger Editor, you will be able to easily navigate through the API docs.

AGH requires user to authenticate when using the API, so let's assume our username is admin and password is password. Invoking API is as simple as adding a HTTP header and encoding admin:password as Base64 string to include in the header - you can use CyberChef for this.

curl -H 'Authorization: Basic YWRtaW46cGFzc3dvcmQK' ...

 Here we are interested in 2 API endpoints:

  • /control/filtering/add_url
  • /control/filtering/remove_url
Swagger Editor shows us exact invocation method with examples:

Sunday, 5 January 2020

Mikrotik + Pi Zero + Pi-hole = advertising sinkhole with fail-safe

Components

  • Mikrotik router with USB port - I tested on RB2011UiAS-2HnD-IN and hAP ac models
  • RouterOS in modern version - I tested with long term (6.44.6)
  • Raspberry Pi Zero - I use old one without "W", with 4GB microSD card running latest Raspbian 10 Buster (minimal, without GUI!)
  • Short micro-USB data cable - because many cheap cables don't do data

Pi Zero actually has more than enough power to run Pi-hole serving even quite large home/family network and running it completely self-contained off Mikrotik seems to work great!


Initial setup

  1. Download and burn the latest Raspbian onto the SD card - I used for this Etcher and 2019-09-26-raspbian-buster-lite.img
  2. Connect SD card to a PC and in partition called boot edit two files to enable Ethernet gadget:
    1. config.txt - at the very end of the file add a line saying dtoverlay=dwc2
    2. cmdline.txt - add modules-load=dwc2,g_ether directly after 'rootwait' and before any other parameters that may (or not) be there
  3. Boot up RPi powering from PC using the port marked as USB on the board - not the PWR IN; it's the one in the centre - only that one does power + gadget
  4. After all boots up, you should be able to run ssh pi@raspberrypi.local (thanks mDNS!) with password raspberry
  5. On the RPi create file called /etc/modprobe.d/g_ether.conf with the following content (single line of text)
    options g_ether idVendor=0x05ac idProduct=0x1402 iProduct=Pi0 iManufacturer=Raspberry
    NOTE - This is required for RPi to show up as LTE interface on Mikrotik!

Saturday, 30 November 2019

Hacking smart plugs for fun and profit

Smarter, the smart way...

You'd like to have your home a bit smarter but not spend a ton of money and you don't like the fact that you have to trust an unnamed 3rd-party company with your data and more importantly access to things that can trigger kinetic actions in your household.

Chinese company Itead is the maker of well known Sonoff devices (do not confuse with audio gear from Sonos). They have a vast range of wifi controlled relays, in various formats and sizes - overall very cool stuff. There is a really nice video on youtube that will give you more idea about what I mean by this.
One of the best parts of Sonoff devices is that they use ESP8266 as the main driver chip and attach relays to it, so being ESP8266 based they are very hackable! That's just what we need!

These days, Itead and others are making smart devices using the same tested pattern and rebrand them under hundreds of names. You will find on Amazon various devices using the same management app (usualy eWeLink or Smart Life), which means OEM devices - good for us!

NOTE:
Since 2019 more and more devices switch from ESP82xx to Realtek chips - the OEM ecosystem is also a curse. For example in 2018 I bought Teckin SP27 smart plug - worked perfect... bought some SP27 and SP23 this week and they run Realtek, so DO NOT BUY those if you want to reflash :-)

What works? I got this set and as of late November 2019 it was still ESP82xx based. Others reported at the same time that this is also working. Basically depends on which batch you get and a bit of luck :-)

Tuesday, 29 January 2019

More range, more fun - ADS-B setup updates

Quick post today...

I've updated my ADS-B receiving station about a week ago and today, most likely due to radio propagation conditions change, I set a new detection range record of 241nm (or 466km) - here's the view from my FlightRadar24 dashboard, and the day's not over yet!


Strangely most detections are due South today, which wasn't the case over the rest of the week (most are N-NW due to window where the antenna is being exactly North facing). This is the magic of radio propagation - band conditions change constantly, sometimes in most surprising way.

Right, so what what were the updates I made last week? I made only one...

Saturday, 17 November 2018

Slimming down 1-node Elastic cluster

If you ever ran Elastic Search especially quick and dirty - single node and default config, you will notice the health is always showing yellow and that it's a proper hog for the system. Well, yes, it will be, especially in default config, as my good friend Justin Borland pointed out.

I'm a complete newbie when it comes to Elastic, deployed few in Docker containers to quickly ingest data and dig in with Kibana, but that was it. Luckily for me Justin is absolute beast when it comes to all things Elastic - he just looked at my node and right on the spot explained what's wrong with it and how to fix/improve.

Basically my default setup was running 5 shards for each of the indices stored in the system, and I had quite a few daily indices already there - we're talking months of DNS research data and web spider runs across thousands of websites... all repeated daily. This means the optimisation to be really effective needs to also deal with what's in there, not just new data I will be adding.

Plan:
  1. Change default template to run only 1 shard and 0 replicas - it's a single node deployment, so anything more complex doesn't make much sense.
  2. Use reindex API to rewrite all of existing indices as single shard versions, the deleting the old ones using 5 shards - there's no other way to do it than through reindexing.
  3. My indices are treated append-only on the day, then become read-only, so we can merge the segments - leaving technical details behind, this will mean no random access later, just linear file reads, but that's perfectly acceptable in my particular use scenario.

Let's do it!

Friday, 2 November 2018

Solution - Rancher 2 (k8s), private registry, self-signed certificates

Since Rancher switched to Kubernetes in version 2.x, I'm exposed to a lot of stupidity and limitations k8s introduced, but I can live with that, at least for a moment... What I couldn't accept was that I could no longer use my private registry (with self-signed certificate) that works perfectly fine with older Rancher (1.6 - before move to k8s).

That is now resolved!

My cluster setup


  • Rancher 2 cluster (based on Kubernetes), all running on latest RancherOS
  • Private registry available only within the LAB network - hence self-signed certificate
  • Registry has an internal host name, resolvable via internal DNS server
  • Registry does not require user accounts, so no need for credentials, but self-signed certificate prevents it from working, resulting with following error when image is pulled
x509: certificate signed by unknown authority

Dead ends


First of all, please ignore RancherOS documentation - last one I found was for version 1.2, current RancherOS is 1.4.2... anyway, it no longer works (it did for older RancherOS and Rancher 1.6 though, but new Rancher is more Kubernetes than anything else). In my research I also read a bunch of bug reports, feature requests, stack exchange articles, etc... mostly waste of time, but they gave me a good idea on rabbit holes to avoid. Some of the more useful reads are here and here, I also have a feeling this will be useful for me quite soon.
Another trick I noticed was that if I followed RancherOS docs above, the registry CA key was overwritten with something else on node reboot.

Solution (a.k.a "works for me")


Go old school Linux admin style:

  1. SSH to the RancherOS node (user is rancher@<node>), having your private CA certificate at hand
  2. As user rancheros try docker pull <registry:port>/<my image> - you should get a CA error
  3. Check your /etc/resolv.conf - mine was regularly overwritten by dhcp but it was not writing name servers correctly - this should be easily fixed by writing what you want to /etc/resolv.conf.tail (in hopes dhcp will append it when it regenerates resolv.conf).
  4. Now the key element - edit the OS wide trusted CA list (hint hint - may disappear after sudo ros os upgrade, but this can be fixed with sudo chattr +i /etc/resolv.conf)  and add your CA certificate there. Running vi /etc/ssl/certs/ca-certificates.crt and copy'n'paste does the trick!
  5. Try docker pull again, now it worked for me.

Friday, 3 June 2016

Recipe - Docker, web apps and Lets Encrypt

Intro


If you're after easy hosting of dockerized web services with automatic certificate enrolment using Lets Encrypt, then the solution is to use 2 docker containers - nginx as a web proxy and Lets Encrypt Companion to handle certificates. LE Companion can provide either LIVE or STAGING certificates, depending on configuration, but you can run only one at a time.

Container definitions below are in a docker-compose format and the recipe below contains absolutely no security hardening of the Docker installation - this is something you need to consider separately

Web proxy

TLSproxy:
  image: 'jwilder/nginx-proxy:latest'
  ports:
    - '80:80'
    - '443:443'
  volumes:
    - '/etc/letsencrypt:/etc/nginx/certs:ro'
    - /etc/nginx/vhost.d
    - /usr/share/nginx/html
    - '/var/run/docker.sock:/tmp/docker.sock:ro'
  environment:
    - 'DEFAULT_HOST=default.vhost.tld'

TLSproxy is nginx based reverse proxy that automatically discovers and configures virtual hosts running on the same machine. See image description on docker hub for details. TL;DR simple approach is:

docker run -d -e VIRTUAL_HOST=blog.domain.tld ghost

Please note, the DEFAULT_HOST variable - it's quite useful to have it set right :-)

Thursday, 18 February 2016

Adding private insecure registry to Rancher nodes

Quick post before I forget - there's quite a few people asking how to get insecure docker registry running on RancherOS node. Here's what worked well for me.

First thing that helps a lot is to have some DNS entry for your registry - remember you will use this hostname quite often, so better set it up now than use IP addresses going forward.
As I run my own internal DNS server with local zones, I have created registry.rancher.lan entry and pointed to the node running registry container.

All of my nodes were already up and running, so I didn't use cloud-config.yml file for that and had to stick to ssh to get it working, but there's nothing to stop you from adding it right there for node installation time. The ssh process is super simple - please note entire command is a single line:

$ sudo ros config set rancher.docker.args "[daemon, --log-opt, max-size=25m, --log-opt, max-file=2, -s, overlay, -G, docker, -H, unix:///var/run/docker.sock, --userland-proxy=false, --insecure-registry=registry.rancher.lan:5000]"
I've marked in bold the key element. Be aware, the syntax is quite sensitive if you use quotes. I had multiple crashes on boot because single quote was converted to python(ish) three single quotes, which of course didn't parse well going forward. Clearly the config tool tries to be smart, so please, let it be and remove quotes in parameters passed in the array.

Finally, reboot and off you go - the node will now find and correctly use the images hosted in your own registry.

Tuesday, 10 February 2015

Raspberry Pi 2 - first impressions


  1. First impression is that (in my opinion) it is visibly faster than the previous one (1st gen. model B with 512MB RAM), even on tasks that can't use more than one CPU core - this is a good sign. The difference is even more visible when comparing to 1st gen. model B with 256MB RAM...
  2. I measured power consumption at the wall using kill-a-watt type plug and here are the results:
    • No SD card inserted (not booting) - 0.6W
    • Booted up and idle, with Ethernet connected - 1.4W
    • CPU cores under load (via sysbench prime number test, with Ethernet):
      • 1 thread - 1.8W, 296 sec to complete
      • 2 threads - 2.0W, 148 sec to complete
      • 4 threads - 2.5W, 74 sec to complete
  3. I tried the Xeon flash bug (or feature) and yes, it works. Of course it doesn't react to LED generated light and the usual laser pointers - I'd love to test it against a real lightning flash but I guess I'll have to wait for weather to change. Here's the Xeon flash test:

  4. Finally, the main sticking point for use experience is slow SD card access, so pick the fastest card you can get - it's worth it!

Sunday, 9 November 2014

haste-server Base URL Hack/Patch

Recently I came across haste-server, a server behind hastebin, which is a pastebin clone written in node.js. The application is minimalistic, fairly simple and works really well, except for one rather major glitch - it takes over the root directory of the whole website.

I've noticed that several people raised an issue on GitHub asking the author for help, but so far nobody shared fully working solution. Some people tried to work reverse proxy magi, others tried to patch the code - with moderate success. Instead of adding to the problem area I thought I'll try to offer a solution - keep in mind I don't know JavaScript ;-)


Tuesday, 28 October 2014

Wake-on-Lan issues with Intel PRO Series NIC

Over the last few months I was experimenting with setting up my ham-radio station for completely remote operation, so once the rare DX comes on air I can work it regardless of where I am at the time.

The idea seems simple but this means that for a start I need to be able to remotely turn on and off all of the devices. Leaving the design itself for another post, the core element of my remote control concept is rather old ThinkPad x60s laptop. This one comes with Intel PRO/1000 Ethernet NIC and I want to use WoL to boot it up remotely.

What is WoL?
It's a simple way to turn on a machine connected to the network by sending it a single ethernet packet. Very useful if you want to boot up a machine for out-of-hours maintenance run or something similar - like in my case.

Problem
WoL works great but only once, so after you shut down the OS there's no way to do remote start again. This is something that many have encountered judging by the amount of forum posts and questions asked about the same issue.

Once I wasted more time than I should on trying to figure out what's going on, the fix turned out to be "trivial". Lesson learned for sure.

Saturday, 1 March 2014

Running AirView2 [EoL] on Windows 8.1

This is purely "note to self" type post for getting End-of-Life AirView2 device (introduced here) to run under the latest version of Windows.


The AirView2 requires an app and a driver. AirView tool installer (msi format) that checks the OS version and aborts installation if it's different than XP or Vista. The viewer app is written in Java but the AirView2 needs a driver as well (technically it will show up as simple COM port afterwards).

Manual Installation:

  1. Download and install Java JRE (ouch!)
  2. Download the latest software (32 or 64bit) from http://www.ubnt.com/airview/downloads
  3. Manually unpack the MSI file to some location. In command line window this goes like:
    msiexec /a AirView-Spectrum-Analyzer-v1.0.11_win32-setup.msi /qb TARGETDIR=C:\AirView2
  4. Plug in the dongle into USB port and go to the Device Manager - you will see AirView2 having driver issues. Update driver and tell Windows to look for a new one under C:\AirView2
  5. Double click on airview-o.jar to run the app - happy scanning!
AirView app doesn't care where it was unpacked so you can move it anywhere you want to ;-)

Monday, 25 November 2013

LG SmartTV (47LW640S) confirmed to be "snooping"

Following some revelations from DoctorBeet's Blog about LG Smart TVs snooping on our watching habits and further information posted on Mark's blog, I realised my parents recently bought one of those... :-)

First of all we should be rational and assume that any "smart device" is doing that. Unfortunately (for LG) this is pretty bad timing for this kind of news to come out in the light of the recent NSA/Snowden/whatever leaks. Oh well, nothing to see and almost moving on....
Here is a screenshot of traffic from a TV running in Poland, model 47LW640S (also visible in the request headers).

TV turned ON


Saturday, 26 October 2013

Virtual radar - Raspberry Pi and RTL-SDR

As you probably know it's been over a year since Raspberry Pi hit the market. Mine spent most of that year in the drawer, so I decided to see if I can use it as low power server for a particular task. One of the ideas I had for a long time was to build a virtual radar type system that would allow me to see airplanes that fly over my area. There are purpose built systems that are quite expensive so why not to do it on a budget and have some fun with it?

ADS-B Basics

Automatic dependent surveillance-broadcast (ADS-B) is a cooperative surveillance technology for tracking aircraft. --Wikipedia

This is one of the ways in which the airplanes report their basic flight parameters (identification, current position, altitude, speed, etc) to the Air Traffic Control. All of this happens over radio broadcasts (completely public) at 1090MHz - at lest this is the frequency we are interested in. The full Wikipedia article is quite interesting and contains more information.

Why bother?

 

If you have ever seen the flightradar24 website before, you have possibly thought (I know I did) about how cool would it be to do it yourself - own one of those virtual radars and maybe even feed the data into flightradar24 to improve their coverage (and get premium account for free)? If you like this idea, you will like the results your own radar station will produce - in general it would be something like this


All of that is easy to build and the cost is really minimal, using either a PC or a Raspberry Pi as I describe in this post.

Saturday, 19 May 2012

Fixing HAProxy configuration in pfSense

Some time ago I was experimenting with pfSense and HAProxy to deploy both as firewall and load balancer for one of the websites I was working on at the time. The key incentive was that pfSense is great BSD based firewall distribution with amazing features offered out of the box, and if that was not enough, you can install additional packages to add features you need.

One of those packages is HAProxy (proxy/load balancer) and both work together very nicely but...

Problem

I have installed pfSense with HAProxy several times, more than several in fact... and every time I did it, the configuration file generated using HAProxy web configurator (integrated with pfSense interface) was broken. First row in the table showing defined backends was empty -  the configuration file itself had just variables but no values. The second entry was just fine... Obviously HAProxy refused to start.

Quick fix

Just so I remember next time what I did. Get shell on pfSense console or install file manager package and edit /usr/local/pkg/haproxy.inc to add the line highlighted below:


Not a rocket science, just shift() the first (empty) backend definition and let the script do the rest.

Note

Manually fixing config file is pointless because new config is generated every time HAProxy (re)starts and the code above is used to generate it.

Tuesday, 8 May 2012

Raspberry Pi meets Edimax EW-7811Un wireless adapter

This post contains my notes - what I did to make it work properly, so next time I build the system, I have a step by step guide. In case you lived under the rock for the last months and don't know what Raspberry Pi is, you should visit www.raspberrypi.org now.

Raspberry Pi

I bought Edimax EW-7811Un adapter for my Pi - small factor, b/g/n type, so why not... especially when vendor says it provides Linux drivers (wohoo!). Sadly as it turns out, compiling drivers on x86 or x64 and ARM architectures can be totally different experience - especially with Raspberry Pi being in it's software infancy. In all seriousness - Pi is for those that like to solve problems (at least at the current stage), but the community works hard to catch up very quickly - great stuff!

Sunday, 4 March 2012

Logfile tail the web way

Recently I needed something like web based equivalent of tail -f and tail -n commands, so I could display running tail or last N lines from specific log file. To avoid reinventing the wheel I started looking at previous works on-line and found some interesting bits here and there - one of the most useful being AJAX Logfile Tailer & Viewer, so I based my work on this one.

The trick is, that as far as it does exactly what I needed, this solution requires web server with PHP... and installing web server (not to mention PHP) is not really what I want on my logserver.

Mojolicious to the rescue!


Mojolicious is a very powerful Perl web framework that comes without bloat (almost unheard of these days!) - all you need is standard Perl interpreter and core Perl modules as they come preinstalled with your Linux distro and you can install Mojolicious - no other dependencies. On Debian systems installation is as simple as

apt-get install libmojolicious-perl

and we're up and running. Writing Mojolicious::Lite app is really simple and the best part is that it comes with it's own, built in web server (operating in several different modes if needed). Sounds like nice way to go - no dedicated web server on the machine, self-contained application, etc. One more thing - writing, testing and deploying the whole code to actual machine took less than 10 minutes!

Thursday, 23 February 2012

Secure backup of untrusted remote hosts

I didn't blog for a long time, so it will be a long post caused by some nightmares I had about not doing proper backups on some of my hosts.

Servers - all those small and big machines most of the geeks own, run or operate. As VPS pricing drops, we see more and more of those low-end, resource strapped servers. Organic growth usually means you start with empty server, some kind of definition what it will be doing and... from there it just goes downhill. How do you backup such VPS? Here is something I use myself.

My backup requirements

  • Automated - it has to run without supervision in roughly regular time intervals, if it's not automated it will never be done (read no backup)
  • Off-site - in case I loose the whole machine for some reason (because RAID is not backup and what fire doesn't destroy, water poured by firemen will)
  • No Cross-Backups - because they require trust relationship between machines and if you think about using cheap VPS'es for cross-backups, remember that you get what you pay for!
  • Automatically delete old backups - to save space, (my) time and money
  • Append only - machine can only write data to its own, designated backup volume but can not delete or modify other volumes (accidents and rogue users do happen)
  • Confidentiality - no unauthorized access backed up data
  • Availability - storage volume has to be highly available so I can not only write to it knowing it's there, but also access backups when I need them
  • Access controls - ability to define granular access rules and enforce append-only usage
  • Economy - it has to have reasonable cost

Thursday, 17 February 2011

How To Outrun A Lion?

You don't have to outrun a lion - it's enough you outrun the guy running next to you.

Funny enough, the same stands for securing your IT infrastructure - if you are in the "low hanging fruit" category, you get owned for sure - possibly before you even notice anything shady going on behind your shiny website. When you raise the bar a bit and step out of the damned circle, most of the attackers will give up on you and move to find some other target that is easier to compromise.Of course that doesn't work for determined attackers that want YOU and nobody else, but that's a story for another time.

What's that smell?

It's a smell of FAIL my friend...

Just recently I was helping two of my friends and doing some forensics on their servers (or rather on what was left out of them) after they noticed something strange was going on.  Long story short, the key part is that the attackers owned those boxes for months before they were discovered. They got in via path of the least resistance - badly written PHP web apps (there's so many of them!), dropped c99 or similar shell and owned the box to their liking.

In general, we suck really bad if it takes us months to detect such hacks.

Here come the benefits of scale

Wherever and whenever I look at any shared hosting providers, dedicated servers and alike, their default configuration is wide open by default. As long as the box is on-line and Nagios doesn't report issues, nobody is actually checking what's going on that box. Basically operators don't care - they provide functionality and they charge you for it. Oh yes, that's exactly what they do - charge you first and then provide a ton of stuff you don't need and don't use - unless you are an attacker that is :-)


Plenty of dangerous PHP functions enabled, dumb/bad configuration of network services and often the networks itself, total lack of monitoring (except for Nagios)... and all of that provided by default, just in case a customer comes back and says 'oh, that breaks functionality I need'; all because that would mean they (operators) have to go back and spend some time on enabling it later. Sure, it's easier to blame it on the "bad hackers in my interwebz" - great business model guys! I believe, that if you build the security into your system from the start, your TCO will be lower than going with defaults (loss of clients due to compromise, cos of bringing system back in service, etc) but that's a business decision of course.

Default configs are similar to default passwords.

Improving security posture

If you are on a shared hosting platform, there's not much you can do really. It's a shared host, so you (or rather the operator) has to find the common denominator - something that will satisfy everybody using this particular host. It's about finding the weakest link and bringing everybody else down to the same level - not good.


If you go with VPS or dedicated server, you can change a lot and it won't cost you a lot of money. Simple things can improve your posture and make it much harder for the attackers to run loose on your servers. Here are just three things you can do for free...

Egress filtering

Do you have an outbound firewall policy set to DROP by default? Can you imagine that in datacenter environment? Can it work well or will be a huge PITA?

Yup, easily doable and not that painful if you think about it. If we consider Linux, you can use iptables for that and I guess you already do have an iptables firewall of some sort that filters inbound packets. Let's extend it a bit - example below is for a simple web server:

# fail close - just in case
/sbin/iptables -P OUTPUT DROP
/sbin/iptables -F OUTPUT
# allow responses - majority of traffic comes here so it's a first rule
/sbin/iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# allow from self to self
/sbin/iptables -A OUTPUT -d 127.0.0.1 -j ACCEPT
# allow DNS servers listed in /etc/resolv.conf
for DNS in `grep "^nameserver" /etc/resolv.conf`; do
        if [ $DNS != "nameserver" ]; then
                /sbin/iptables -A OUTPUT -p udp --dport 53 -d $DNS -j ACCEPT
        fi
done
# allow SMTP out to email admins
/sbin/iptables -A OUTPUT -p tcp --dport 25 -d $DOMAIN_MX -j ACCEPT
# allow NTP outbound, local NTP is nice to have!
/sbin/iptables -A OUTPUT -p udp --dport 123 -d $LOCAL_NTP -j ACCEPT
# allow connections to our Linux repository mirror for updates
/sbin/iptables -A OUTPUT -p tcp -d $LINUX_REPO -j ACCEPT
# generic log and drop all
# /etc/syslog.conf => kern.=debug     /var/log/firewall
/sbin/iptables -A OUTPUT -j LOG --log-level 7  --log-prefix "FW-DROP: "
/sbin/iptables -A OUTPUT -j REJECT --reject-with icmp-host-prohibited

Simple? Yes!
Does it raise the bar? Yes!
Do I have to write IP addresses everywhere? No - iptables will resolve hostnames used in rules and I've noticed that for example if my $LINUX_REPO has several IP addresses, iptables actually created an entry for each of them.
But I can't do anything else! That's exactly the point - you shouldn't do anything else on a web server, unless there is a justified need for that (say access SQL database on another host, etc).

Wrapping up - all your web traffic (responses from web server and other services hosted here) will go into state matching rule, then you care for DNS, access to your own MX (only this one unless you have very good reason to do otherwise), NTP and distro updates are really nice to have, then drop all the other traffic. You could add rules for remote (off-site) logging, so you know when something tries to call out/pops your box.

Now, when an attacker drops his php shell he is pretty much very limited (no call back home, no portscans, no IRC bots, etc), unless he escalates access to root, but hey - how about a network based firewall implementing above?

Server hardening

Wow, you could write a book on that, but let's stick to the basics:
Install only the software you really really need (do you need that gcc and all dev libraries to run your web server) - remove what was installed and is not needed - you can always put it back if you need it later!
Turn off all services that shouldn't be running - my rule of thumb is to bring the system to the point, where I can run it entirely without any firewall, because there is no services to hide.
Keep your software updated - cron is your friend (to see what updates are available)
Kernel hardening - SELinux and Grsecurity (+RBAC) seem to be the key candidates here. Yes, that can take a lot of time to set up, but in most cases it's well worth it.

Just try to imagine how annoying it has to be for an attacker to own the box via web app, get root via local privilege escalation and not be able to install his rootkit (and hide) because kernel is monolithic (no loadable modules support) and has grsecurty baked in, with IP logging on resource overstep and other nice features it offers.

BTW here's the funny note left in one of the toolkits I lifted from one of friend's servers - what you make out of it is up to you. Oh... and credit to Ingo Molnár for his exploits and awesome comments in their source code ;-)


Logging and monitoring

Best things are free right? How about using syslog that comes with the system to send the logs off-site? Make a small box somewhere and simply pump it all out, so you have an off-site record in case of unwanted guests showing up.
Not enough bandwidth you say? There's an app for that - pump logs out via OpenVPN using LZO compression with or without encryption (hint: you can set the cipher to none) and as my test show, this can drop your logging bandwidth by around 80% and on top of that you can do traffic shaping in OpenVPN itself.

Now, having logs and not looking at them is a waste of resources, unless you are "checkbox security" organization and need it for compliance on paper... Depending on your pocket condition, you can use simple scripts to get what you need or get some free tools that sift through and visualize large amounts of data. For example Splunk has a free edition (up to 500MB raw log input per day) and there is many other (mostly paid for) products that you could use. Even "cloud based" services like Loggly (also offers free developer account) are available these days - simply pick something that works for you.


It is not a rocket science - it's really about common sense, so calm down and carry on.


UPDATE:
As @denishowe pointed out "it seems we need a checklist for dumb providers with the list of things to disable and another checklist for dumb users, so they can enable what they really need" - yes, that might just work :-)

Wednesday, 24 November 2010

Building cheap console server

This time from the department of almost wasted time...

We all know that serial ports come very handy when you need to (re)configure something like a switch/server/firewall or similar device. In theory you can do that over TCP/IP nowadays with one hint - you need to have connectivity. All would be ok if not the fact that those very switches/firewalls you want to reconfigure actually provide the connectivity you need :-)

The Idea


Now... why spend hundreds of pounds/dollars on off-the shelf kit? Sure, it's cool, properly built and works unless you mess it up, but where's the fun part?! Today I needed a very very quick and cheap solution, so:

  1. SheevaPlug - £114.00
  2. 13-port USB hub - £19.99
  3. USB-serial dongles (pl2303) - £14.99 each
This way I have fully networked console server with 4 ports just under £200 - acceptable, especially when the whole thing is running off DHCP and calls home via OpenVPN - very easy to deploy!

Tricky bits

Generic Sheeva has one USB host port and hub has 13 of them - I want to send it off to remote location and have somebody plug it in and not mess up what's where. Trick is to write appropriate udev rules to detect adapters and give them ttyUSBn names according to physical port on the hub.


All would be fine and easy if it worked as documented - sadly it doesn't. First problem was that ATTRS{devpath} (as returned by udevadm info --attribute-walk -n /dev/ttyUSBn that allows to distinguish usb ports) was used by rule in tests but wasn't propagated properly on none of my Debian or Ubuntu boxes. Then I tried to match KERNELS for parent devices - nope... if you go too far up the tree it doesn't see s**t :-/


The Solution

Finally I got the working rule set - long story short, here it is:

KERNEL=="ttyUSB*", SUBSYSTEM=="tty", DRIVERS=="pl2303", KERNELS=="1-1.1:1.0",   NAME="ttyUSB0"
KERNEL=="ttyUSB*", SUBSYSTEM=="tty", DRIVERS=="pl2303", KERNELS=="1-1.4.1:1.0", NAME="ttyUSB1"
KERNEL=="ttyUSB*", SUBSYSTEM=="tty", DRIVERS=="pl2303", KERNELS=="1-1.4.2:1.0", NAME="ttyUSB2"
KERNEL=="ttyUSB*", SUBSYSTEM=="tty", DRIVERS=="pl2303", KERNELS=="1-1.4.3:1.0", NAME="ttyUSB3"
KERNEL=="ttyUSB*", SUBSYSTEM=="tty", DRIVERS=="pl2303", KERNELS=="1-1.4.4:1.0", NAME="ttyUSB4"
KERNEL=="ttyUSB*", SUBSYSTEM=="tty", DRIVERS=="pl2303", KERNELS=="1-1.3.4:1.0", NAME="ttyUSB5"
KERNEL=="ttyUSB*", SUBSYSTEM=="tty", DRIVERS=="pl2303", KERNELS=="1-1.3.3:1.0", NAME="ttyUSB6"
KERNEL=="ttyUSB*", SUBSYSTEM=="tty", DRIVERS=="pl2303", KERNELS=="1-1.3.2:1.0", NAME="ttyUSB7"
KERNEL=="ttyUSB*", SUBSYSTEM=="tty", DRIVERS=="pl2303", KERNELS=="1-1.3.1:1.0", NAME="ttyUSB8"
KERNEL=="ttyUSB*", SUBSYSTEM=="tty", DRIVERS=="pl2303", KERNELS=="1-1.2.4:1.0", NAME="ttyUSB9"
KERNEL=="ttyUSB*", SUBSYSTEM=="tty", DRIVERS=="pl2303", KERNELS=="1-1.2.3:1.0", NAME="ttyUSB10"
KERNEL=="ttyUSB*", SUBSYSTEM=="tty", DRIVERS=="pl2303", KERNELS=="1-1.2.2:1.0", NAME="ttyUSB11"
KERNEL=="ttyUSB*", SUBSYSTEM=="tty", DRIVERS=="pl2303", KERNELS=="1-1.2.1:1.0", NAME="ttyUSB12"


I had to use KERNELS match as above to have variables seen by the rule. I still don't know (and at this moment don't care any more) why it didn't work as documented...

The bottom line is that it works, it can be done way cheaper than commercial solutions, literally at the fraction of cost - if you don't mind the spider-ish look of it :-)


Update:
Hat tip to @herkii for pointing out another approach.