Today I will explain how to do traffic limit with OpenBSD and PF. This is not hard at all if you want something easy, the man page pf.conf(5) in QUEUEING section is pretty good but it may disturbing when you don’t understand how it works. This is not something I master, I’m not sure of the behaviour in some cases but the following example works as I tested it ! :)
Internet is down at home, I want to use my phone as 4G router trough my OpenBSD laptop which will act as router. I don’t want the quota (some Gb) to be eaten in a few seconds, this connection allow to download up to 10 Mb/s so it can go quickly !
We will limit the total bandwidth to 1M (~ 110 kb/s) for people behind the NAT. It will be slow, but we will be sure that nothing behind the NAT like a program updating, cloud stuff synchronizing or videos in auto play won’t consume our quota.
Edit /etc/pf.conf accordigly to your network
internet="urndis0" lan="em0" # we define our available bandwidth queue main on $lan bandwidth 100M # we will let 1M but we will allow # 3M during 200 ms when initiating connection to keep the web a bit interactive queue limited parent main bandwidth 1M min 0K max 1M burst 3M for 200ms default set skip on lo # we do NAT here match out on egress inet from !(egress:network) to any nat-to (egress:0) block all pass out quick inet # we apply the queue here on EVERYTHING coming from the internet pass in on $lan set queue limited
This ONLY defines queue for DOWNLOADING, you can only set the queue on the lan interface, this won’t work on egress (network interface having internet) because you can’t limit what go in your interface, it’s already there when you want to limit.
Per protocol ?
You can define queues per remote port by creating new queues and doing something like this :
pass in on $lan proto tcp port ssh set queue ssh pass in on $lan proto tcp port www set queue web
Per host ?
As before, you can apply queues on IP host/range rather than protocols, or you can even mix both if you want.
The limit function changed in OpenBSD 5.5, everything you can read on the internet about ALTQ isn’t working anymore.
I have a pfsense appliance (Netgate 2440) with a usb console port, while it used to be a serial port, now devices seems to have a usb one. If you plug an usb wire from an openbsd box to it, you woull see this in your dmesg
uslcom0 at uhub0 port 5 configuration 1 interface 0 "Silicon Labs CP2104 USB to UART Bridge Controller" rev 2.00/1.00 addr 7 ucom0 at uslcom0 portno 0
To connect to it from OpenBSD, use the following command :
doas cu -l /dev/cuaU0 -s 115200
And you’re done
Here is a tiny code to get a connection to an SSL/TLS server. I am writing an IRC client and an IRC bot too and it’s better to connect through a secure channel.
This requires usocket and cl+ssl :
(usocket:with-client-socket (socket stream *server* *port*) (let ((ssl-stream (cl+ssl:make-ssl-client-stream stream :external-format '(:iso-8859-1 :eol-style :lf) :unwrap-stream-p t :hostname *server*))) (format ssl-stream "hello there !~%") (force-output ssl-stream)))
My website is now available with Gopher protocol ! I really like this protocol. If you don’t know it, I encourage you reading this page : Why is Gopher still relevant ?.
This has been made possible by modifying the tool generating the website pages to make it generating gopher compatible pages. This was a bit of work but I am now proud to have it working.
I have also made a “big” change into the generator, it now rely on a “markdown-to-html” tool which sadden me a bit. Before that, I was using ham-mode in emacs which was converting html on the fly to markdown so I can edit in markdown, and was exporting into html on save. This had pros and cons. Nothing more than a lisp interpreter was needed on the system generating the files, but I was sometimes struggling with ham-mode because the conversion was destructive. Multiple editing in a row of the same file was breaking code blocks, because it wasn’t exported the same way each time until it wasn’t a code block anymore. There are some articles that I update sometimes to keep it up-to-date or fix an error in it, and it was boring to fix the code everytime. Having the original markdown text was mandatory for gopher export, and is now easier to edit with any tool.
There is a link to my gopher site on the right of this page. You will need a gopher client to connect to it. There is an android client working, also Firefox can have an extension to become compatible (gopher support was native before it have been dropped). You can find a list of clients on Wikipedia.
Gopher is nice, don’t let it die.
Profanity is a command-line ncurses based XMPP (Jabber) client. It’s easy to use and seem inspired from irssi for the interface. It’s available in net/profanity.
It’s really easy to use and the documentation on its website is really clear.
To log-in, just type /connect myusername@mydomain and after the password prompt, you will be connected. Easy.
This Port of the week is a bit special because sadly, the port isn’t available on OpenBSD. The port is mbuffer (which you can find in misc/mbuffer).
I discovered it while looking for a way to enhance one of my network stream scripts. I have some scripts that get a dump of a postgresql base through SSH, copy it from stdin to a file with tee and send it out to the local postgres, the command line looks like
ssh remote-base-server "pg_dump my_base | gzip -c -f -" | gunzip -f | tee dumps/my_base.dump | psql my_base
I also use the same kind of command to receive a ZFS snapshot from another server.
But there is an issue, the end server is relatively slow, postgresql and ZFS will eat lot of data from stdin and then it will stop for sometimes writing on the disk, when they are ready to take new data, it’s slow to fill them. This is where mbuffer takes places. This tool permit to add a buffer that will take data from stdin and fill its memory (that you set on the command line), so when the slowest part of the command is ready to take data, mbuffer will empty its memory into the pipe, so the slowlest command isn’t waiting to get filled before working again.
The new command looks like that for a buffer of 300 Mb
ssh remote-base-server "pg_dump my_base | gzip -c -f -" | gunzip -f | tee dumps/my_base.dump | mbuffer -s 8192 -m 300M | psql my_base
mbuffer also comes with a nice console output, showing
percentage/consumption of memory filled
in @ 1219 KiB/s, out @ 1219 KiB/s, 906 MiB total, buffer 0% full
In this example the server is too fast so there is no wait, the buffer isn’t used (0% full).
mbuffer can also listen on TCP, unix socket and have a lot of parameters that I didn’t try, if you think that can be useful for you, just go for it !
I am starting a periodic posting for something I wanted to do since a long time. Take a port in the tree and introduce it quickly. There are tons of ports in the tree that we don’t know about. So, I will write frequently about ports that I use frequently and that I find useful, if you read this, maybe I will find a new tool to your collection of “useful program”. :-)
For a first one, I would like to present net/bwm-ng. Its name stands for “_BandWitch Monitor next-generation_”, it allows the user to watch in real-time the bandwith usage of the different network interfaces. By default, it will update the display every 0.5 second. You can change the frequency of updating with ‘+’ and ‘-’
Let see the bindings of the interactive mode :
- ‘t’ will cycle between current rate, maximum peak, sum, average on 30 seconds.
- ‘n’ will cycle between data sources, on OpenBSD it defaults to “getifaddrs” and you can also choose “sysctl” or “netstat -i”.
- ‘d’ will change the unit, by default it shows KB but you can change to another units that suits better your current data.
Summary output after downloading a file
bwm-ng v0.6.1 (probing every 5.700s), press 'h' for help input: getifaddrs type: sum - iface Rx Tx Total ============================================================================== lo0: 0.00 B 0.00 B 0.00 B em0: 19.89 MB 662.82 KB 20.54 MB pflog0: 0.00 B 0.00 B 0.00 B ------------------------------------------------------------------------------ total: 19.89 MB 662.82 KB 20.54 MB
It’s available on *BSD, Linux and maybe others.
In OpenBSD ports tree, check net/bwm-ng.
If someday under FreeBSD you have a system with multiple IP address on the same network and you need to use a specific IP for a route, you have to use the -ifa parameter in the route command.
In our example, we have to use the address 192.168.1.140 to access the network 192.168.30.0 through the router 192.168.1.1, this is as easy as the following.
route add -net 192.168.30.0 192.168.1.1 -ifa 192.168.1.140
You can add this specific route like any other route in your rc.conf as usual, just add the -ifa X.X.X.X parameter.