Multi-WAN DNS in pfSense
Update: I later figured out there are many other places pfSense restarts Unbound, so this is simply not worth the effort. I reversed the changes & moved Unbound to another box and using just DNS forwarder on pfSense — which is used by the Unbound server.
Having multiple broadband connections at home, I have a pfSense which takes care of load balancing and firewalling. pfSense is pretty good in almost everything, except one thing that was annoying me a lot — That it restarted the DNS Resolver (Unbound) every time either of my WAN connections restarted (one of my ISPs restarts […]
ZFS convert stripe to striped-mirror
I’m a huge fan of ZFS because of its performance and other features like snapshots, transparent compression. In fact I had switched to FreeBSD for servers just because it had native ZFS support. But as of Ubuntu 16.04, ZFS is officially supported for non-root partitions.
Now I’m migrating a FreeBSD server to Ubuntu 16.04 with ZFS for data storage – this is happening because I need support for some special hardware which has drivers only for Linux and I do not have a spare server machine of […]
Group based HTTP basic authentication using Nginx and MySQL with help of Lua
Recently I moved from Apache to Nginx on one of my servers due to increase in traffic. But I was using HTTP Basic authentication with group based authorization on Apache in this manner:
1 2 3 4 5 6 7 8 |
<Location /foo> AuthType Basic AuthName Restricted AuthBasicProvider file AuthUserFile /etc/apache2/htpasswd AuthGroupFile /etc/apache2/groups Require group somegroup </Location> |
1 2 3 4 |
location ~ ^/restricted { set $user_group 'somegroup'; access_by_lua_file '/etc/nginx/authenticate.lua'; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
-- basic configuration of the script local cookie_domain = ".yourdomain.com" local db_username = "dbuser" local db_password = "dbpasswrod" local db_socket = "/tmp/mysql.sock" local db_name = "dbname" -- end configuration local session = require "resty.session".open{ cookie = { domain = cookie_domain } } local remote_password if ngx.var.http_authorization then local tmp = ngx.var.http_authorization tmp = tmp:sub(tmp:find(' ')+1) tmp = ngx.decode_base64(tmp) remote_password = tmp:sub(tmp:find(':')+1) end function authentication_prompt() session.data.valid_user = false session.data.user_group = nil session:save() ngx.header.www_authenticate = 'Basic realm="Restricted"' ngx.exit(401) end function authenticate(user, password, group) local mysql = require "resty.mysql" local db, err, errno, sqlstate, res, ok db = mysql:new() if not db then ngx.log(ngx.ERR, "Failed to create mysql object") ngx.exit(500) end db:set_timeout(2000) ok, err, errno, sqlstate = db:connect{ path = db_socket, database = db_name, user = db_username, password = db_password } if not ok then ngx.log(ngx.ERR, "Unable to connect to database: ", err, ": ", errno, " ", sqlstate) ngx.exit(500) end user = ngx.quote_sql_str(user) password = ngx.quote_sql_str(password) local query = "select 1 from http_users where username = %s and password = SHA2(%s, 224) and (find_in_set('superadmin', groups) > 0 or find_in_set('%s', groups) > 0)" query = string.format(query, user, password, group); res, err, errno, sqlstate = db:query(query) if res and res[1] then session.data.valid_user = true session.data.user_group = group session:save() else authentication_prompt() end end if session.present and (session.data.valid_user and session.data.user_group == ngx.var.user_group) then return elseif ngx.var.remote_user and remote_password then authenticate(ngx.var.remote_user, remote_password, ngx.var.user_group) else authentication_prompt() end |
The group authentication script looks for users and groups in a table called http_users. Since this […]
FreeBSD IPFW NAT and Jails
IPFW in FreeBSD has built-in support for NATing and the configuration syntax is same as that of natd. It took me quite some time to figure out how to NAT for jails while ensuring that certain jails can have public IPs.
Configure the nat on one of the IP addresses:
1 |
ipfw nat 123 config ip a.b.c.d |
1 2 |
ipfw add 100 nat 123 from any to a.b.c.d in ipfw add 101 check-state |
1 2 3 4 5 6 7 8 9 10 11 12 13 |
index=300 for port in $tcp_service_ports; do ipfw add $index allow tcp from any to me $port in ipfw add $index allow tcp from me $port to any out index=$((index+1)) done index=400 for port in $udp_service_ports; do ipfw add $index allow udp from any to me $port in ipfw add $index allow udp from me $port to any out index=$((index+1)) done |
1 |
ipfw add 800 nat 123 ip4 from 10.0.0.0/8 to any out |
FreeBSD ipfw: add_dyn_rule: Cannot allocate rule
One of the servers I run has FreeBSD 10. It hosts a high traffic Magento site. Magento being a very heavy application, requires a dedicated server. The site’s performance is very bad when it is hosted on VPS — or perhaps that depends on provider / needs tuning. Not my site. My task was to move it to dedicated server so I don’t have to consider all that stuff.
As someone new to FreeBSD, I try to stick to tools and utilities that are provided by FreeBSD itself and do not rely on those provided by other BSDs. This rule is […]
The move from Linux to FreeBSD
About 2 months ago, I had a spare VPS at my host, Hetzner. So I decided to play with FreeBSD which was being offered for Hetzner servers and VPSes.
That’s how the whole thing started. I didn’t have much problems getting the concepts because it belongs to *nix family of OSes and I have been a pure Linux user since 2008.
First of all the basic difference between FreeBSD and GNU/Linux is that Linux is just the kernel and GNU is the userland. In layman’s terms, the hardware interface is called Linux, while the rest of the […]