<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>b1c1l1 blog</title><link href="https://www.b1c1l1.com/blog/" rel="alternate"></link><link href="https://www.b1c1l1.com/blog/feed/atom.xml" rel="self"></link><id>https://www.b1c1l1.com/blog/</id><updated>2020-04-19T12:54:24-07:00</updated><entry><title>Linux Home Router Download Bufferbloat Analysis</title><link href="https://www.b1c1l1.com/blog/2020/04/19/linux-home-router-download-bufferbloat-analysis/" rel="alternate"></link><published>2020-04-19T12:54:24-07:00</published><updated>2020-04-19T12:54:24-07:00</updated><author><name>Benjamin Lee</name></author><id>tag:www.b1c1l1.com,2020-04-19:/blog/2020/04/19/linux-home-router-download-bufferbloat-analysis/</id><summary type="html">&lt;p&gt;In my previous article, I mentioned that download shaping with rate limiting can avoid download bufferbloat.  In this article, I wanted to take a closer look at the factors that contribute to download bufferbloat and how rate limiting works around the problem.&lt;/p&gt;</summary><content type="html">&lt;h4&gt;Introduction&lt;/h4&gt;
&lt;p&gt;In my previous article, &lt;a href="/blog/2020/03/26/linux-home-router-traffic-shaping-with-fq_codel/"&gt;Linux Home Router Traffic Shaping With FQ_CoDel&lt;/a&gt;, I mentioned that download shaping with rate limiting can avoid download bufferbloat.  In this article, I wanted to take a closer look at the factors that contribute to download bufferbloat and how rate limiting works around the problem.&lt;/p&gt;
&lt;h4&gt;Background&lt;/h4&gt;
&lt;p&gt;Transmission Control Protocol (TCP) uses congestion control algorithms to adapt to network conditions.  TCP senders increase the window size to use all available bandwidth until congestion is detected.  However, detecting remote congestion is difficult in practice and the techniques for doing so are continuing to evolve.&lt;/p&gt;
&lt;p&gt;Traditionally, TCP congestion control algorithms (e.g. Reno, CUBIC) assumed that congestion causes packet loss.  Bufferbloat breaks this assumption by queueing packets, rather than dropping them, during periods of congestion.  Despite being delayed, these packets are eventually delivered and ACKed, preventing senders from detecting and adapting to the congestion.&lt;/p&gt;
&lt;p&gt;Some TCP congestion control algorithms (e.g. Vegas, BBR) can detect congestion by measuring delay.  However, some concerns have been raised regarding how bandwidth is shared between flows using loss-based algorithms and flows using delay-based algorithms.  &lt;a href="https://cloud.google.com/blog/products/gcp/tcp-bbr-congestion-control-comes-to-gcp-your-internet-just-got-faster"&gt;Google created and uses TCP BBR in production&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Explicit Congestion Notification (ECN) extends IP and TCP by enabling congested network nodes to signal congestion explicitly by marking packets rather than dropping them.  However, ECN adoption has been slow due to misbehaving devices dropping packets with ECN bits set.  Most servers now support ECN for clients that request it, but most clients still do not enable ECN by default.  FQ_CoDel enables ECN marking by default.&lt;/p&gt;
&lt;h4&gt;Download Bufferbloat&lt;/h4&gt;
&lt;p&gt;Download bufferbloat is difficult to analyze because it is highly variable and depends on many factors outside of our control.  These factors include, but are not limited to: TCP congestion control algorithm, ECN support, round-trip time (RTT), traffic shaping, network congestion.&lt;/p&gt;
&lt;p&gt;In particular, TCP congestion control algorithms run on the sender, which in the case of downloads is the remote server.  If the server is configured to use a delay-based congestion control algorithm such as BBR, which is designed to reduce latency despite the presence of bufferbloat, then it will be especially difficult to measure and reproduce bufferbloat-related problems.&lt;/p&gt;
&lt;h4&gt;Rate Limiting&lt;/h4&gt;
&lt;p&gt;One workaround for download bufferbloat is rate limiting.  Depending on how it is implemented this may also be called ingress shaping.  An example implementation is available in my &lt;a href="/blog/2020/03/26/linux-home-router-traffic-shaping-with-fq_codel/"&gt;previous article&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Using rate limiting to avoid download bufferbloat is counterintuitive because it involves dropping valid packets that will need to be retransmitted.  It also seems inefficient to sacrifice a significant amount of download bandwidth and leave the link underutilized.&lt;/p&gt;
&lt;p&gt;It's worth reiterating that rate limiting is a workaround.  When senders send us too much data, our options for asking them to slow down are limited.  Although some senders might respond to delay and/or ECN, nearly all senders will respond to packets dropped due to rate limiting.&lt;/p&gt;
&lt;p&gt;Here is a simplified visualization of the download bufferbloat problem and how rate limiting works around the problem.  This example is based on traditional TCP congestion control algorithms such as Reno using additive increase multiplicative decrease.  As the window size increases, download bandwidth is exceeded and packets are buffered upstream, causing latency.  Using rate limiting to drop downloaded packets early ensures that window size increases above steady state remain below the actual link speed.&lt;/p&gt;
&lt;p class="image"&gt;&lt;a href="/media/download-bufferbloat-and-rate-limiting.png"&gt;&lt;img src="/media/download-bufferbloat-and-rate-limiting.png" alt="Download Bufferbloat and Rate Limiting Diagram"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;Caveats&lt;/h4&gt;
&lt;p&gt;Ideally, upstream devices would implement active queue management on their transmit queues to us and no download shaping would be necessary on our end.&lt;/p&gt;
&lt;p&gt;Download shaping is at best a workaround for well-behaved senders that respond to packet loss by slowing down.  Download shaping will have limited value in other scenarios such as floods, and may even be counterproductive if packet loss results in amplification.&lt;/p&gt;
&lt;h4&gt;Additional Reading&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="/blog/2020/03/26/linux-home-router-traffic-shaping-with-fq_codel/"&gt;b1c1l1 blog: Linux Home Router Traffic Shaping With FQ_CoDel&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.apnic.net/2017/05/09/bbr-new-kid-tcp-block/"&gt;APNIC Blog: BBR, the new kid on the TCP block&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cloud.google.com/blog/products/gcp/tcp-bbr-congestion-control-comes-to-gcp-your-internet-just-got-faster"&gt;Google Cloud Blog: TCP BBR congestion control comes to GCP – your Internet just got faster&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://queue.acm.org/detail.cfm?id=3022184"&gt;ACM Queue: BBR: Congestion-Based Congestion Control&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><category term="sysadmin"></category><category term="linux"></category><category term="router"></category><category term="bufferbloat"></category></entry><entry><title>Linux Home Router Traffic Shaping With FQ_CoDel</title><link href="https://www.b1c1l1.com/blog/2020/03/26/linux-home-router-traffic-shaping-with-fq_codel/" rel="alternate"></link><published>2020-03-26T19:12:37-07:00</published><updated>2020-03-26T19:12:37-07:00</updated><author><name>Benjamin Lee</name></author><id>tag:www.b1c1l1.com,2020-03-26:/blog/2020/03/26/linux-home-router-traffic-shaping-with-fq_codel/</id><summary type="html">&lt;p&gt;CoDel (Controlled Delay) is an Active Queue Management algorithm that drops packets based on delay rather than queue length.  FQ_CoDel (Fair Queueing Controlled Delay) combines CoDel with fair queueing to share bandwidth between flows.&lt;/p&gt;</summary><content type="html">&lt;h4&gt;Background&lt;/h4&gt;
&lt;p&gt;Bufferbloat refers to excessively large network buffers causing high latency.&lt;/p&gt;
&lt;p&gt;Many operating systems are configured by default to enable good performance on low-latency high-bandwidth links, such as data centers and corporate LANs.  For example, with Gigabit Ethernet (1 Gbps) 1,500-byte packets can be sent at a rate of approximately 81,274 packets/sec.  At this rate, a buffer of 1,000 packets represents a delay of ~12 ms.&lt;/p&gt;
&lt;pre&gt;1,000,000,000 bits/sec × 1 byte/8 bits × 1 packet/1,538 bytes ≈ 81,274 packets/sec&lt;/pre&gt;
&lt;pre&gt;1,000 packets × 1 sec/81,274 packets × 1,000 ms/sec ≈ 12 ms&lt;/pre&gt;
&lt;p&gt;However, at low bandwidths, such as the 1 Mbps upload speed offered by my home ISP, a 1,000-packet buffer would represent a massive 12,000 ms delay.  Worse still, by the time the tail of the queue is reached, it is unlikely that those packets still need to be delivered, since the users that sent them have already retried or given up.&lt;/p&gt;
&lt;p&gt;Traditional QoS (Quality of Service) systems use packet metadata such as port numbers and TCP flags to identify high priority traffic.  For example, an administrator can prioritize SIP traffic on port 5060 for VoIP calls or reserve bandwidth for TCP ACKs.  However, these systems are complex to administer and are difficult to mantain as applications and requirements change.  Additionally, these systems are becoming less relevant due to the increasing amounts of opaque traffic transported over HTTPS and VPNs.&lt;/p&gt;
&lt;p&gt;Home internet connections exacerbate the bufferbloat problem due to having asymmetric links with low upload bandwidths in addition to poorly configured modems.  Home users also have increasing amounts of data being uploaded, such as photos, video conferencing, and security cameras.&lt;/p&gt;
&lt;h4&gt;CoDel and FQ_CoDel&lt;/h4&gt;
&lt;p&gt;CoDel (Controlled Delay) is an Active Queue Management algorithm that drops packets based on delay rather than queue length.  FQ_CoDel (Fair Queueing Controlled Delay) combines CoDel with fair queueing to share bandwidth between flows.  CoDel was introduced in a 2012 publication, &lt;a href="https://queue.acm.org/detail.cfm?id=2209336"&gt;Controlling Queue Delay&lt;/a&gt;.  The initial Linux implementations of &lt;a href="https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=76e3cc126bb223013a6b9a0e2a51238d1ef2e409"&gt;sch_codel.c&lt;/a&gt; and &lt;a href="https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=4b549a2ef4bef9965d97cbd992ba67930cd3e0fe"&gt;sch_fq_codel.c&lt;/a&gt; were committed soon after.&lt;/p&gt;
&lt;p&gt;Although CoDel is designed to be a "no-knobs" algorithm, tuning is required for low-bandwidth links.  For example, at 1 Mbps transmitting a 1,500-byte packet takes ~12 ms, so the CoDel target should be increased from the default 5 ms.  Additionally, the &lt;a href="https://www.bufferbloat.net/projects/codel/wiki/Best_practices_for_benchmarking_Codel_and_FQ_Codel"&gt;Bufferbloat Wiki&lt;/a&gt; recommends disabling ECN for uplinks less than 4 Mbps.&lt;/p&gt;
&lt;h4&gt;Implementation&lt;/h4&gt;
&lt;p&gt;The simplest implementation is to create a single HTB bucket with FQ_CoDel on the "WAN" interface connected to the modem.  The rate limit must be lower than the available upload bandwidth (~95%) to ensure that packets are not buffered by the modem, however you will have to experiment to find the right value for your connection.&lt;/p&gt;
&lt;p class="image"&gt;&lt;a href="/media/traffic-shaping-upload.png"&gt;&lt;img src="/media/traffic-shaping-upload.png" alt="Traffic Shaping Upload Diagram"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;# tc qdisc add dev eno1.2 root handle 1: htb default 1
# tc class add dev eno1.2 parent 1: classid 1:1 htb rate 950kbit quantum 1514
# tc qdisc add dev eno1.2 parent 1:1 fq_codel target 15ms noecn&lt;/pre&gt;
&lt;p&gt;If download shaping is required, you can use a similar configuration on the "LAN" interface connected to your home devices.  Download bufferbloat is a complex subject and will be discussed further in a &lt;a href="/blog/2020/04/19/linux-home-router-download-bufferbloat-analysis/"&gt;future article&lt;/a&gt;.  Usually you will have to use a significantly lower rate limit for downloads (~85%).  If you have significant download traffic originating from the router, you may want to consider ingress shaping with an ifb device instead.&lt;/p&gt;
&lt;p class="image"&gt;&lt;a href="/media/traffic-shaping-download.png"&gt;&lt;img src="/media/traffic-shaping-download.png" alt="Traffic Shaping Download Diagram"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;# tc qdisc add dev eno1.1 root handle 1: htb default 1
# tc class add dev eno1.1 parent 1: classid 1:1 htb rate 13mbit quantum 1514
# tc qdisc add dev eno1.1 parent 1:1 fq_codel&lt;/pre&gt;
&lt;h4&gt;Alternatives&lt;/h4&gt;
&lt;p&gt;Some users may want to perform additional shaping by creating multiple HTB buckets with different rate limits and classifying packets using nftables, iptables, or tc filters.  There are many &lt;a href="https://github.com/dtaht/ceropackages-3.10/blob/master/net/debloat/files/simple_qos.sh"&gt;examples&lt;/a&gt; of these kinds of configurations, however I do not think it is necessary for most use cases.&lt;/p&gt;
&lt;p&gt;Alternatively, you might want to consider using &lt;a href="https://manpages.debian.org/buster/iproute2/tc-cake.8.en.html"&gt;CAKE&lt;/a&gt;, which adds interesting features such as pre-configured priority queues, fair queueing across LAN hosts when using NAT, and ACK filtering.&lt;/p&gt;
&lt;h4&gt;Testing&lt;/h4&gt;
&lt;p&gt;One way to test your configuration is to run ping while saturating your bandwidth (e.g. uploading a large file).  If you are suffering from bufferbloat, ping will show significant delays and drops.  I also recommend the &lt;a href="https://www.dslreports.com/speedtest"&gt;DSLReports speed test&lt;/a&gt; and &lt;a href="https://fast.com/"&gt;Fast.com speed test&lt;/a&gt; because they include tools for measuring latency.&lt;/p&gt;
&lt;p&gt;Here is an example of running ping while saturating a 1 Mbps upload connection:&lt;/p&gt;
&lt;pre&gt;64 bytes from 1.1.1.1: icmp_seq=256 ttl=55 time=2944 ms
[dropped packet icmp_seq=257]
64 bytes from 1.1.1.1: icmp_seq=258 ttl=55 time=3109 ms
64 bytes from 1.1.1.1: icmp_seq=259 ttl=55 time=3211 ms
64 bytes from 1.1.1.1: icmp_seq=260 ttl=55 time=3235 ms&lt;/pre&gt;
&lt;p&gt;Based on the observed 3,000 ms delay and assuming a FIFO queue we can estimate that the modem transmit queue length is ~250 packets.&lt;/p&gt;
&lt;p&gt;After implementing traffic shaping with FQ_CoDel, ping shows an improvement:&lt;/p&gt;
&lt;pre&gt;64 bytes from 1.1.1.1: icmp_seq=306 ttl=55 time=27.3 ms
64 bytes from 1.1.1.1: icmp_seq=307 ttl=55 time=25.9 ms
64 bytes from 1.1.1.1: icmp_seq=308 ttl=55 time=28.8 ms
64 bytes from 1.1.1.1: icmp_seq=309 ttl=55 time=33.1 ms&lt;/pre&gt;
&lt;p&gt;Much better!&lt;/p&gt;
&lt;h4&gt;Additional Reading&lt;/h4&gt;
&lt;ul class="bullets"&gt;
&lt;li&gt;&lt;a href="/blog/2020/04/19/linux-home-router-download-bufferbloat-analysis/"&gt;b1c1l1 blog: Linux Home Router Download Bufferbloat Analysis&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://tools.ietf.org/html/rfc8290"&gt;RFC 8290: The Flow Queue CoDel Packet Scheduler and Active Queue Management Algorithm&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://queue.acm.org/detail.cfm?id=2209336"&gt;ACM Queue: Controlling Queue Delay&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://lwn.net/Articles/496509/"&gt;LWN.net: The CoDel queue management algorithm&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bufferbloat.net/projects/codel/wiki/Best_practices_for_benchmarking_Codel_and_FQ_Codel/"&gt;Bufferbloat Wiki: Best Practices for Benchmarking CoDel and FQ CoDel&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://manpages.debian.org/buster/iproute2/tc-fq_codel.8.en.html"&gt;Debian Manpages: tc-fq_codel(8)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><category term="sysadmin"></category><category term="linux"></category><category term="router"></category><category term="bufferbloat"></category></entry><entry><title>Encrypted Recursive DNS with DNS over TLS, Unbound, and Cloudflare</title><link href="https://www.b1c1l1.com/blog/2018/04/23/encrypted-recursive-dns-with-dns-over-tls-unbound-and-cloudflare/" rel="alternate"></link><published>2018-04-23T14:17:35-07:00</published><updated>2018-04-23T14:17:35-07:00</updated><author><name>Benjamin Lee</name></author><id>tag:www.b1c1l1.com,2018-04-23:/blog/2018/04/23/encrypted-recursive-dns-with-dns-over-tls-unbound-and-cloudflare/</id><summary type="html">&lt;p&gt;The recent announcement of Cloudflare's new privacy-focused recursive DNS service 1.1.1.1 prompted me to revisit the options for encrypted recursive DNS and finally enable DNS over TLS on my workstations.&lt;/p&gt;</summary><content type="html">&lt;p&gt;The recent &lt;a href="https://blog.cloudflare.com/announcing-1111/"&gt;announcement of Cloudflare's new privacy-focused recursive DNS service 1.1.1.1&lt;/a&gt; prompted me to revisit the options for encrypted recursive DNS and finally enable DNS over TLS on my workstations.&lt;/p&gt;
&lt;p&gt;As a brief reminder, Transport Layer Security (TLS) and its predecessor Secure Sockets Layer (SSL) improve privacy online by using symmetric encryption to prevent eavesdropping and using public-key cryptography to authenticate recipients.&lt;/p&gt;
&lt;p&gt;Due to increasing awareness and new revelations regarding sophisticated spying operations by governments and corporations, there has been a significant increase in the adoption of HTTPS (HTTP over TLS) over the past several years.  According to Google, &lt;a href="https://security.googleblog.com/2018/02/a-secure-web-is-here-to-stay.html"&gt;over 68% of Chrome traffic on Android and Windows is now protected&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;However, recursive DNS, which is used before an HTTPS connection can be established, remains largely vulnerable to the same attacks that are used against unencrypted HTTP.&lt;/p&gt;
&lt;p&gt;Fortunately, there are several options for protecting recursive DNS, including DNS over TLS, DNS over HTTPS, and DNSCrypt.  Each option has various tradeoffs and may not be available depending on your specific operating system and internet provider.  For example, you will need to ensure that the relevant ports are not blocked.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.unbound.net/"&gt;Unbound&lt;/a&gt; is a DNS resolver with native support for DNS over TLS.  In version 1.7.0 you can use the appropriately named forward-tls-upstream option, while the same option was named forward-ssl-upstream in version 1.6.0.  Older versions supported the global ssl-upstream option.&lt;/p&gt;
&lt;p&gt;To set up a forwarding resolver with Unbound, simply create a forward-zone entry with name "." and the appropriate upstream addresses.  &lt;a href="https://developers.cloudflare.com/1.1.1.1/dns-over-tls/"&gt;Cloudflare supports DNS over TLS on 1.1.1.1 and 1.0.0.1 on port 853&lt;/a&gt;.  The final result in your unbound.conf should look something like this:&lt;/p&gt;
&lt;pre&gt;server:
    tls-cert-bundle: /etc/ssl/certs/ca-certificates.crt

forward-zone:
    name: "."
    forward-tls-upstream: yes
    forward-addr: 2606:4700:4700::1111@853#cloudflare-dns.com
    forward-addr: 2606:4700:4700::1001@853#cloudflare-dns.com
    forward-addr: 1.1.1.1@853#cloudflare-dns.com
    forward-addr: 1.0.0.1@853#cloudflare-dns.com&lt;/pre&gt;
&lt;p&gt;It is necessary to specify tls-cert-bundle to enable TLS certificate verification and the forward-addr suffix '#cloudflare-dns.com' to specify the expected subject name on the certificate.&lt;/p&gt;
&lt;p&gt;Additional reading:&lt;/p&gt;
&lt;ul class="bullets"&gt;
&lt;li&gt;&lt;a href="https://blog.cloudflare.com/announcing-1111/"&gt;Cloudflare Blog: Announcing 1.1.1.1: the fastest, privacy-first consumer DNS service&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://security.googleblog.com/2018/04/dns-over-tls-support-in-android-p.html"&gt;Google Security Blog: DNS over TLS support in Android P Developer Preview&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://security.googleblog.com/2018/02/a-secure-web-is-here-to-stay.html"&gt;Google Security Blog: A secure web is here to stay&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://arstechnica.com/information-technology/2018/04/how-to-keep-your-isps-nose-out-of-your-browser-history-with-encrypted-dns/"&gt;Ars Technica: How to keep your ISP’s nose out of your browser history with encrypted DNS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://nlnetlabs.nl/documentation/unbound/unbound.conf/"&gt;NLnet Labs Documentation - Unbound - unbound.conf.5&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://wiki.archlinux.org/index.php/unbound"&gt;Arch Linux Wiki: Unbound&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><category term="sysadmin"></category><category term="dns"></category><category term="security"></category></entry><entry><title>Loading the GeoIP Module with nginx 1.10.0 on FreeBSD</title><link href="https://www.b1c1l1.com/blog/2016/05/03/loading-the-geoip-module-with-nginx-1100-on-freebsd/" rel="alternate"></link><published>2016-05-03T04:56:46-07:00</published><updated>2016-05-03T04:56:46-07:00</updated><author><name>Benjamin Lee</name></author><id>tag:www.b1c1l1.com,2016-05-03:/blog/2016/05/03/loading-the-geoip-module-with-nginx-1100-on-freebsd/</id><summary type="html">&lt;p&gt;After upgrading to nginx 1.10.0 on my FreeBSD machines, I found that nginx would no longer start.&lt;/p&gt;</summary><content type="html">&lt;p&gt;After upgrading to &lt;a href="http://nginx.org/"&gt;nginx&lt;/a&gt; 1.10.0 on my FreeBSD machines, I found that nginx would no longer start.&lt;/p&gt;
&lt;pre&gt;$ sudo /usr/local/etc/rc.d/nginx restart
Performing sanity check on nginx configuration:
nginx: [emerg] unknown directive "geoip_country" in /usr/local/etc/nginx/nginx.conf:42
nginx: configuration file /usr/local/etc/nginx/nginx.conf test failed&lt;/pre&gt;
&lt;p&gt;Looking at the commit logs led me to &lt;a href="http://www.freshports.org/commit.php?category=www&amp;port=nginx&amp;files=yes&amp;message_id=201604262224.u3QMOox8073160@repo.freebsd.org"&gt;revision 414084&lt;/a&gt;, which notes that the GeoIP module and several other modules are now built as dynamic modules.&lt;/a&gt;
&lt;p&gt;So I looked for where the GeoIP module was installed.&lt;/p&gt;
&lt;pre&gt;$ pkg info -l nginx | fgrep geoip
        /usr/local/libexec/nginx/ngx_http_geoip_module.so&lt;/pre&gt;
&lt;p&gt;And updated the configuration to load the GeoIP module dynamically.&lt;/p&gt;
&lt;pre&gt;load_module "/usr/local/libexec/nginx/ngx_http_geoip_module.so";&lt;/pre&gt;
&lt;p&gt;Additional reading:&lt;/p&gt;
&lt;ul class="bullets"&gt;
&lt;li&gt;&lt;a href="https://www.nginx.com/blog/dynamic-modules-nginx-1-9-11/"&gt;Introducing Dynamic Modules in NGINX 1.9.11&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><category term="sysadmin"></category><category term="freebsd"></category><category term="nginx"></category></entry><entry><title>Disk Encryption with dm-crypt and LUKS on Linux</title><link href="https://www.b1c1l1.com/blog/2015/09/20/disk-encryption-with-dm-crypt-and-luks-on-linux/" rel="alternate"></link><published>2015-09-20T19:27:55-07:00</published><updated>2015-09-20T19:27:55-07:00</updated><author><name>Benjamin Lee</name></author><id>tag:www.b1c1l1.com,2015-09-20:/blog/2015/09/20/disk-encryption-with-dm-crypt-and-luks-on-linux/</id><summary type="html">&lt;p&gt;Linux Unified Key Setup (LUKS) is a dm-crypt extension and the preferred way to set up disk encryption with dm-crypt on Linux.&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;a href="https://www.kernel.org/doc/Documentation/device-mapper/dm-crypt.txt"&gt;dm-crypt&lt;/a&gt; is a Linux Device-mapper target that provides transparent encryption of block devices using the kernel crypto API.  Plain dm-crypt supports only one passphrase and does not store any metadata on-disk.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://gitlab.com/cryptsetup/cryptsetup"&gt;Linux Unified Key Setup (LUKS)&lt;/a&gt; is a dm-crypt extension and the preferred way to set up disk encryption with dm-crypt.  LUKS is a disk encryption standard that adds a header and a key-slot at the start of the device, called a LUKS container.  LUKS supports multiple passphrases that can be individually changed and revoked.  Passphrases are protected using the PBKDF2 key derivation function, which is also described in &lt;a href="https://tools.ietf.org/html/rfc2898"&gt;RFC 2898&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;First, securely erase the target device.&lt;/p&gt;
&lt;ul class="bullets"&gt;
&lt;li&gt;
&lt;p&gt;For traditional hard disk drives, simply overwrite the device.  Depending on your security requirements you may need to use random data instead of zeros.&lt;/p&gt;
&lt;pre&gt;cat /dev/zero &gt; /dev/sdz&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;For solid-state drives (SSDs), clear the memory cells.  This can usually be accomplished via &lt;a href="https://ata.wiki.kernel.org/index.php/ATA_Secure_Erase"&gt;ATA Secure Erase&lt;/a&gt; but varies by device.  I do not recommend overwriting an SSD, which would increase device wear and cause reduced write performance due to write amplification.&lt;/p&gt;
&lt;pre&gt;sudo hdparm --user-master u --security-set-pass password /dev/sdz
sudo hdparm --user-master u --security-erase password /dev/sdz&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Next, set up a LUKS device with your desired encryption parameters.  The appropriate level of encryption is situation-dependent.  I highly recommend choosing algorithms for which your system can use hardware acceleration (for example, the &lt;a href="http://software.intel.com/en-us/articles/intel-advanced-encryption-standard-instructions-aes-ni"&gt;Intel AES-NI&lt;/a&gt; instruction set that was introduced with Westmere).  Choosing cipher and hash algorithms is discussed at length elsewhere and is beyond the scope of this article.&lt;/p&gt;
&lt;ol class="blocknumbers"&gt;
&lt;li&gt;
&lt;p&gt;Initialize a LUKS device and set the initial passphrase.  For the block cipher I chose XTS-AES with a 256-bit key (XTS-AES 128), which is recommended in &lt;a href="http://csrc.nist.gov/publications/nistpubs/800-38E/nist-sp-800-38E.pdf"&gt;NIST SP 800-38E&lt;/a&gt; and used in &lt;a href="http://support.apple.com/kb/ht4790"&gt;Apple FileVault 2&lt;/a&gt;.  For the PBKDF2 passphrase hash I chose SHA-256 with 5 seconds of processing time.&lt;/p&gt;
&lt;pre&gt;sudo cryptsetup --cipher aes-xts-plain64 --key-size 256 --hash sha256 --iter-time 5000 --use-random --verify-passphrase luksFormat /dev/sdz&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Open and map the encrypted device.  Use --allow-discards if using an SSD that supports TRIM.&lt;/p&gt;
&lt;pre&gt;sudo cryptsetup --allow-discards luksOpen /dev/sdz secure&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create and mount a filesystem on the encrypted device.  Use -o discard if using an SSD that supports TRIM.&lt;/p&gt;
&lt;pre&gt;sudo mkfs.ext4 /dev/mapper/secure
sudo mount -o noatime,discard /dev/mapper/secure /secure&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Finally, configure your system to map and mount the encrypted device during boot.  These steps vary by distribution and whether you are encrypting the root filesystem, which requires updating your initramfs.&lt;/p&gt;
&lt;p&gt;Here is an example configuring a non-root encrypted device on Gentoo Linux.&lt;/p&gt;
&lt;ol class="blocknumbers"&gt;
&lt;li&gt;
&lt;p&gt;Add the LUKS device to /etc/conf.d/dmcrypt.&lt;/p&gt;
&lt;pre&gt;target="secure"
source="/dev/sdz"
options="--allow-discards"&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Add the dmcrypt service to the boot runlevel.&lt;/p&gt;
&lt;pre&gt;sudo rc-update add dmcrypt boot&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Add the encrypted filesystem to /etc/fstab.&lt;/p&gt;
&lt;pre&gt;/dev/mapper/secure      /secure         ext4            noatime,discard 0 2&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Additional reading:&lt;/p&gt;
&lt;ul class="bullets"&gt;
&lt;li&gt;&lt;a href="https://gitlab.com/cryptsetup/cryptsetup/wikis/FrequentlyAskedQuestions"&gt;cryptsetup Frequently Asked Questions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://gitlab.com/cryptsetup/cryptsetup/wikis/LUKS-standard/on-disk-format.pdf"&gt;LUKS On-Disk Format Specification&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://csrc.nist.gov/publications/nistpubs/800-38E/nist-sp-800-38E.pdf"&gt;Recommendation for Block Cipher Modes of Operation: The XTS-AES Mode for Confidentiality on Storage Devices&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://eprint.iacr.org/2012/374.pdf"&gt;Infiltrate the Vault: Security Analysis and Decryption of Lion Full Disk Encryption&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://wiki.archlinux.org/index.php/Dm-crypt/Device_encryption"&gt;Arch Linux Wiki: dm-crypt/Device encryption&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><category term="sysadmin"></category><category term="linux"></category><category term="security"></category></entry><entry><title>MacBookPro8,2 Kernel Patches for Linux 3.1.1</title><link href="https://www.b1c1l1.com/blog/2011/11/19/macbookpro82-kernel-patches-for-linux-311/" rel="alternate"></link><published>2011-11-19T13:53:39-08:00</published><updated>2011-11-19T13:53:39-08:00</updated><author><name>Benjamin Lee</name></author><id>tag:www.b1c1l1.com,2011-11-19:/blog/2011/11/19/macbookpro82-kernel-patches-for-linux-311/</id><summary type="html">&lt;p&gt;I have compiled a set of patches for the Linux kernel that improves support for the 15-inch MacBookPro8,2.&lt;/p&gt;</summary><content type="html">&lt;p&gt;I have run &lt;a href="http://www.gentoo.org/"&gt;Gentoo Linux&lt;/a&gt; on multiple generations of the &lt;a href="http://www.apple.com/macbookpro/"&gt;MacBook Pro&lt;/a&gt; since its introduction in 2006:&lt;/p&gt;
&lt;ul class="bullets"&gt;
&lt;li&gt;MacBookPro1,1&lt;/li&gt;
&lt;li&gt;MacBookPro5,3&lt;/li&gt;
&lt;li&gt;MacBookPro8,2&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;However, Apple uses bleeding edge and sometimes proprietary hardware in their products, which can be problematic for users of operating systems other than Mac OS because Apple does not provide drivers for those operating systems.  This is especially true with the latest generation of hardware, which includes the second generation Intel Core processors, codenamed Sandy Bridge, with on-socket integrated Intel HD Graphics.&lt;/p&gt;
&lt;p&gt;Consequently, I have compiled a set of patches for the &lt;a href="http://www.kernel.org/"&gt;Linux kernel&lt;/a&gt; that improves support for the 15-inch MacBookPro8,2:&lt;/p&gt;
&lt;pre&gt;blee@supra ~ $ sudo dmidecode -s system-product-name
MacBookPro8,2
blee@supra ~ $ lspci -nn
00:00.0 Host bridge [0600]: Intel Corporation 2nd Generation Core Processor Family DRAM Controller [8086:0104] (rev 09)
00:01.0 PCI bridge [0604]: Intel Corporation Xeon E3-1200/2nd Generation Core Processor Family PCI Express Root Port [8086:0101] (rev 09)
00:01.1 PCI bridge [0604]: Intel Corporation Sandy Bridge PCI Express Root Port [8086:0105] (rev 09)
00:02.0 VGA compatible controller [0300]: Intel Corporation 2nd Generation Core Processor Family Integrated Graphics Controller [8086:0126] (rev 09)
00:16.0 Communication controller [0780]: Intel Corporation Cougar Point HECI Controller #1 [8086:1c3a] (rev 04)
00:1a.0 USB Controller [0c03]: Intel Corporation Cougar Point USB Universal Host Controller #5 [8086:1c2c] (rev 05)
00:1a.7 USB Controller [0c03]: Intel Corporation Cougar Point USB Enhanced Host Controller #2 [8086:1c2d] (rev 05)
00:1b.0 Audio device [0403]: Intel Corporation Cougar Point High Definition Audio Controller [8086:1c20] (rev 05)
00:1c.0 PCI bridge [0604]: Intel Corporation Cougar Point PCI Express Root Port 1 [8086:1c10] (rev b5)
00:1c.1 PCI bridge [0604]: Intel Corporation Cougar Point PCI Express Root Port 2 [8086:1c12] (rev b5)
00:1c.2 PCI bridge [0604]: Intel Corporation Cougar Point PCI Express Root Port 3 [8086:1c14] (rev b5)
00:1d.0 USB Controller [0c03]: Intel Corporation Cougar Point USB Universal Host Controller #1 [8086:1c27] (rev 05)
00:1d.7 USB Controller [0c03]: Intel Corporation Cougar Point USB Enhanced Host Controller #1 [8086:1c26] (rev 05)
00:1f.0 ISA bridge [0601]: Intel Corporation HM65 Express Chipset Family LPC Controller [8086:1c49] (rev 05)
00:1f.2 SATA controller [0106]: Intel Corporation Cougar Point 6 port SATA AHCI Controller [8086:1c03] (rev 05)
00:1f.3 SMBus [0c05]: Intel Corporation Cougar Point SMBus Controller [8086:1c22] (rev 05)
01:00.0 VGA compatible controller [0300]: ATI Technologies Inc Whistler [AMD Radeon HD 6600M Series] [1002:6741]
01:00.1 Audio device [0403]: ATI Technologies Inc Device [1002:aa90]
02:00.0 Ethernet controller [0200]: Broadcom Corporation NetXtreme BCM57765 Gigabit Ethernet PCIe [14e4:16b4] (rev 10)
02:00.1 SD Host controller [0805]: Broadcom Corporation NetXtreme BCM57765 Memory Card Reader [14e4:16bc] (rev 10)
03:00.0 Network controller [0280]: Broadcom Corporation BCM4331 802.11a/b/g/n [14e4:4331] (rev 02)
04:00.0 FireWire (IEEE 1394) [0c00]: Agere Systems FW643 PCI Express1394b Controller (PHY/Link) [11c1:5901] (rev 08)&lt;/pre&gt;
&lt;p&gt;These patches will also be useful for users of the 13-inch MacBookPro8,1 and 17-inch MacBookPro8,3 but I have not tested those models because I do not have access to them.&lt;/p&gt;
&lt;p&gt;The following patches are for Linux 3.1.1:&lt;/p&gt;
&lt;ul class="bullets"&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="/media/patches/linux-3.1.1/apple_bl-gmux.patch"&gt;apple_bl-gmux.patch&lt;/a&gt;&lt;/p&gt;&lt;p&gt;The display backlight on the MacBookPro8,2 is controlled by the Apple gMux.  This patch adds Apple gMux support to the apple_bl driver to enable control of the display backlight.&lt;/p&gt;&lt;p&gt;The following kernel parameters must be specified to use the Apple gMux to control the display backlight:&lt;/p&gt;&lt;pre&gt;acpi_backlight=vendor apple_bl.use_gmux=1&lt;/pre&gt;&lt;p&gt;Related links:&lt;/p&gt;&lt;ul class="bullets"&gt;&lt;li&gt;&lt;a href="http://ubuntuforums.org/showpost.php?p=10694990&amp;postcount=259"&gt;http://ubuntuforums.org/showpost.php?p=10694990&amp;amp;postcount=259&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="/media/patches/linux-3.1.1/apple_gmux.patch"&gt;apple_gmux.patch&lt;/a&gt;&lt;/p&gt;&lt;p&gt;The MacBookPro8,2 includes two GPUs: the integrated Intel HD Graphics 3000 and the discrete ATI Radeon HD 6750M.  In Mac OS, the discrete GPU is activated when an external monitor is connected or certain graphics-intensive applications are launched.  This patch adds a driver for the Apple gMux to enable switching between GPUs using the vga_switcheroo mechanism.  This patch is unnecessary when booting into BIOS emulation mode because the UEFI firmware prevents the integrated GPU from being accessed in BIOS emulation mode.&lt;p&gt;Related links:&lt;/p&gt;&lt;ul class="bullets"&gt;&lt;li&gt;&lt;a href="http://ubuntuforums.org/showpost.php?p=10848581&amp;postcount=456"&gt;http://ubuntuforums.org/showpost.php?p=10848581&amp;amp;postcount=456&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="/media/patches/linux-3.1.1/b43-ht-phy.patch"&gt;b43-ht-phy.patch&lt;/a&gt;&lt;/p&gt;&lt;p&gt;The &lt;a href="http://www.broadcom.com/products/Wireless-LAN/802.11-Wireless-LAN-Solutions/BCM4331"&gt;Broadcom BCM4331&lt;/a&gt; wireless chip in the MacBookPro8,2 is currently unsupported in the mainline kernel.  This patch adds support for HT-PHY devices, including the BCM4331, to the &lt;a href="http://www.linuxwireless.org/en/users/Drivers/b43"&gt;b43&lt;/a&gt; driver.  I generated this patch by pulling the latest versions of the b43 driver and the related modules, bcma and ssb, from the &lt;a href="http://git.kernel.org/?p=linux/kernel/git/linville/wireless-testing.git;a=summary"&gt;wireless-testing.git tree&lt;/a&gt;.  The b43 driver is currently the only driver with BCM4331 support, but the &lt;a href="http://linuxwireless.org/en/users/Drivers/brcm80211"&gt;brcm80211&lt;/a&gt; driver may add BCM4331 support in the near future.&lt;/p&gt;&lt;p&gt;Related links:&lt;/p&gt;&lt;ul class="bullets"&gt;&lt;li&gt;&lt;a href="http://lists.infradead.org/pipermail/b43-dev/2011-August/001978.html"&gt;http://lists.infradead.org/pipermail/b43-dev/2011-August/001978.html&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="/media/patches/linux-3.1.1/efifb-hi-res.patch"&gt;efifb-hi-res.patch&lt;/a&gt;&lt;/p&gt;&lt;p&gt;My MacBookPro8,2 includes a high-resolution 1680x1050 display, which meant that the hard coded display information in the efifb driver was not correct for my display.  This patch updates the efifb driver with the proper display information for the high-resolution display.&lt;/p&gt;&lt;p&gt;The display information was obtained using DTrace in Mac OS:&lt;/p&gt;&lt;pre&gt;blee@supra ~ $ sudo ioreg -lw0 | grep product-name | cut -d'"' -f4
MacBookPro8,2
blee@supra ~ $ sudo dtrace -qn 'BEGIN {
&amp;gt; boot_args = (struct boot_args *) (`PE_state).bootArgs;
&amp;gt; printf("FrameBufferBase: 0x%08x\n", boot_args-&amp;gt;Video.v_baseAddr);
&amp;gt; printf("PixelsPerScanLine: %d\n", boot_args-&amp;gt;Video.v_rowBytes/4);
&amp;gt; printf("HorizontalResolution: %d\n", boot_args-&amp;gt;Video.v_width);
&amp;gt; printf("VerticalResolution: %d", boot_args-&amp;gt;Video.v_height);
&amp;gt; exit(0);
&amp;gt; }'
FrameBufferBase: 0x90010000
PixelsPerScanLine: 1728
HorizontalResolution: 1680
VerticalResolution: 1050&lt;/pre&gt;&lt;p&gt;Related links:&lt;/p&gt;&lt;ul class="bullets"&gt;&lt;li&gt;&lt;a href="https://bugzilla.redhat.com/show_bug.cgi?id=528232"&gt;https://bugzilla.redhat.com/show_bug.cgi?id=528232&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="/media/patches/linux-3.1.1/i915-lvds_channels.patch"&gt;i915-lvds_channels.patch&lt;/a&gt;&lt;/p&gt;&lt;p&gt;By default, the i915 driver probes the video BIOS to determine the number of LVDS channels.  However, this probing fails to correctly determine the number of LVDS channels on the MacBookPro8,2.  This patch allows the number of LVDS channels to be set manually.&lt;/p&gt;&lt;p&gt;The following kernel parameter must be specified to enable dual channel mode:&lt;/p&gt;&lt;pre&gt;i915.lvds_channels=2&lt;/pre&gt;&lt;p&gt;Related links:&lt;/p&gt;&lt;ul class="bullets"&gt;&lt;li&gt;&lt;a href="http://lists.freedesktop.org/archives/intel-gfx/2011-March/009469.html"&gt;http://lists.freedesktop.org/archives/intel-gfx/2011-March/009469.html&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="/media/patches/linux-3.1.1/quirks-mbp_force_ahci.patch"&gt;quirks-mbp_force_ahci.patch&lt;/a&gt;&lt;/p&gt;&lt;p&gt;When booting into BIOS emulation mode, the UEFI firmware puts the SATA controller into legacy IDE mode.  This patch adds a quirk to force the SATA controller into AHCI mode.  This patch is unnecessary when booting into EFI mode because the SATA controller uses AHCI by default in EFI mode.&lt;/p&gt;&lt;p&gt;The following kernel parameter must be specified in order to force the SATA controller into AHCI mode:&lt;/p&gt;&lt;pre&gt;quirks.mbp_force_ahci=1&lt;/pre&gt;&lt;p&gt;Related links:&lt;/p&gt;&lt;ul class="bullets"&gt;&lt;li&gt;&lt;a href="https://bugs.launchpad.net/mactel-support/+bug/817017"&gt;https://bugs.launchpad.net/mactel-support/+bug/817017&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://ubuntuforums.org/showpost.php?p=10685211&amp;postcount=230"&gt;http://ubuntuforums.org/showpost.php?p=10685211&amp;amp;postcount=230&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="/media/patches/linux-3.1.1/radeon-read_bios_from_firmware.patch"&gt;radeon-read_bios_from_firmware.patch&lt;/a&gt;&lt;/p&gt;&lt;p&gt;When booting into EFI mode, the UEFI firmware does not load a video BIOS into memory.  This lack of a video BIOS prevents both the radeon and fglrx drivers from functioning.  This patch allows the radeon driver to read the video BIOS from a firmware file instead of from memory.  The firmware file can be generated by dumping the video BIOS while booted into BIOS emulation mode.&lt;/p&gt;&lt;p&gt;The following command can be used to dump the video BIOS while booted into BIOS emulation mode:&lt;/p&gt;&lt;pre&gt;dd if=/dev/mem of=/lib/firmware/radeon/vbios.bin bs=65536 skip=12 count=1&lt;/pre&gt;&lt;p&gt;Related links:&lt;/p&gt;&lt;ul class="bullets"&gt;&lt;li&gt;&lt;a href="https://bugs.freedesktop.org/show_bug.cgi?id=26891"&gt;https://bugs.freedesktop.org/show_bug.cgi?id=26891&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;</content><category term="sysadmin"></category><category term="linux"></category><category term="macbook pro"></category></entry><entry><title>Using UTF-8 (Unicode) on FreeBSD</title><link href="https://www.b1c1l1.com/blog/2011/05/09/using-utf-8-unicode-on-freebsd/" rel="alternate"></link><published>2011-05-09T00:14:37-07:00</published><updated>2011-05-09T00:14:37-07:00</updated><author><name>Benjamin Lee</name></author><id>tag:www.b1c1l1.com,2011-05-09:/blog/2011/05/09/using-utf-8-unicode-on-freebsd/</id><summary type="html">&lt;p&gt;UTF-8 is a Unicode character encoding that is backwards compatible with US-ASCII.  FreeBSD is not configured to use UTF-8 by default but it is easy to enable.&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;a href="http://www.unicode.org/"&gt;Unicode&lt;/a&gt; is a set of character encodings that are compatible with the Universal Coded Character Set (UCS) defined by &lt;a href="http://www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.htm?csnumber=51273"&gt;ISO/IEC 10646&lt;/a&gt;.  Unicode was designed to replace all previous character encodings such as the &lt;a href="http://webstore.ansi.org/RecordDetail.aspx?sku=ANSI+INCITS+4-1986+%28R2007%29"&gt;American Standard Code for Information Interchange (US-ASCII)&lt;/a&gt; and &lt;a href="http://www.iso.org/iso/search/extendedsearchstandards.htm?from_js=true&amp;type=adv&amp;displayResult=true&amp;published=on&amp;formKeyword=&amp;title=on&amp;description=on&amp;formISO_number=8859&amp;formPart_number=&amp;formDocument_type=ALL&amp;formDocument_lang=ALL&amp;formSupp_type=&amp;formICS=&amp;formStage_code=&amp;repost=1&amp;formDate_stage=0&amp;formOther_date=&amp;formCommittee=&amp;formSub_committee=&amp;formSubmit=Search"&gt;ISO/IEC 8859&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;UTF-8, which is also described in &lt;a href="http://tools.ietf.org/html/rfc3629"&gt;RFC 3629&lt;/a&gt;, is a variable-length Unicode character encoding that is backwards compatible with US-ASCII.  That is, all US-ASCII characters have the same encoding under both US-ASCII and UTF-8.  Due to the widespread use of US-ASCII in computing environments, this backwards compatibility makes UTF-8 convenient to deploy and therefore a popular choice for multilingual computing environments.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.freebsd.org/"&gt;FreeBSD&lt;/a&gt;, like many UNIX-based operating systems, is unfortunately not configured to use UTF-8 by default.  This sometimes causes confusion about whether Unicode is supported on FreeBSD.  Fortunately, it is easy to enable UTF-8 on FreeBSD.&lt;/p&gt;
&lt;ol class="blocknumbers"&gt;
&lt;li&gt;&lt;p&gt;Determine the appropriate UTF-8 locale for your language and country.  &lt;a href="http://www.freebsd.org/cgi/man.cgi?query=locale&amp;apropos=0&amp;sektion=1&amp;manpath=FreeBSD+8.2-RELEASE&amp;format=html"&gt;locale(1)&lt;/a&gt; can be used to print the names of all available locales.&lt;/p&gt;&lt;pre&gt;locale -a | grep '\.UTF-8$'&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update the charset, lang, and setenv attributes in &lt;a href="http://www.freebsd.org/cgi/man.cgi?query=login.conf&amp;apropos=0&amp;sektion=5&amp;manpath=FreeBSD+8.2-RELEASE&amp;format=html"&gt;login.conf(5)&lt;/a&gt;.  It is recommended that LC_COLLATE be set to C because some programs still require ASCII ordering in order to function correctly.&lt;/p&gt;
&lt;ul class="bullets"&gt;
&lt;li&gt;&lt;p&gt;To enable UTF-8 on a system-wide basis, update the default login class in /etc/login.conf.&lt;/p&gt;&lt;pre&gt;blee@eclipse ~ $ diff -u /usr/src/etc/login.conf /etc/login.conf
--- /usr/src/etc/login.conf     2011-03-10 13:48:59.000000000 -0800
+++ /etc/login.conf     2011-05-08 16:44:01.000000000 -0700
@@ -26,7 +26,7 @@
        :passwd_format=md5:\
        :copyright=/etc/COPYRIGHT:\
        :welcome=/etc/motd:\
-       :setenv=MAIL=/var/mail/$,BLOCKSIZE=K,FTP_PASSIVE_MODE=YES:\
+       :setenv=MAIL=/var/mail/$,BLOCKSIZE=K,FTP_PASSIVE_MODE=YES,LC_COLLATE=C:\
        :path=/sbin /bin /usr/sbin /usr/bin /usr/games /usr/local/sbin /usr/local/bin ~/bin:\
        :nologin=/var/run/nologin:\
        :cputime=unlimited:\
@@ -44,7 +44,9 @@
        :pseudoterminals=unlimited:\
        :priority=0:\
        :ignoretime@:\
-       :umask=022:
+       :umask=022:\
+       :charset=UTF-8:\
+       :lang=en_US.UTF-8:


 #&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To enable UTF-8 on a per-user basis, update ~/.login_conf.  This is useful on servers that you do not administer and therefore cannot make system-wide changes.&lt;/p&gt;&lt;pre&gt;blee@eclipse ~ $ cat ~/.login_conf
me:\
        :charset=UTF-8:\
        :lang=en_US.UTF-8:\
        :setenv=LC_COLLATE=C:&lt;/pre&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If /etc/login.conf was modified, run &lt;a href="http://www.freebsd.org/cgi/man.cgi?query=cap_mkdb&amp;apropos=0&amp;sektion=1&amp;manpath=FreeBSD+8.2-RELEASE&amp;format=html"&gt;cap_mkdb(1)&lt;/a&gt; to rebuild the login class capabilities database.&lt;/p&gt;&lt;pre&gt;sudo cap_mkdb /etc/login.conf&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Exit all existing sessions that have the old locale settings.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Verify that the new settings took effect by running &lt;a href="http://www.freebsd.org/cgi/man.cgi?query=locale&amp;apropos=0&amp;sektion=1&amp;manpath=FreeBSD+8.2-RELEASE&amp;format=html"&gt;locale(1)&lt;/a&gt;.&lt;/p&gt;&lt;pre&gt;blee@eclipse ~ $ locale
LANG=en_US.UTF-8
LC_CTYPE="en_US.UTF-8"
LC_COLLATE=C
LC_TIME="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_ALL=&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If applicable, make application-specific configuration changes to enable UTF-8.  Note that this has become increasingly unnecessary as applications have begun respecting locale settings.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Restart all applications that were started with the old locale settings.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Finally, here is the obligatory screenshot.&lt;/p&gt;
&lt;div class="image"&gt;
&lt;p class="image"&gt;&lt;a href="/media/irssi-unicode.png"&gt;&lt;img src="/media/irssi-unicode.png" width="572" height="396" alt="An excerpt from Markus Kuhn's Unicode/UTF-8 demo in Irssi running in GNU Screen over OpenSSH in Konsole." /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p class="caption"&gt;An excerpt from &lt;a href="http://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-demo.txt"&gt;Markus Kuhn's Unicode/UTF-8 demo&lt;/a&gt; in &lt;a href="http://irssi.org/"&gt;Irssi&lt;/a&gt; running in &lt;a href="http://www.gnu.org/software/screen/"&gt;GNU Screen&lt;/a&gt; over &lt;a href="http://www.openssh.com/"&gt;OpenSSH&lt;/a&gt; in &lt;a href="http://konsole.kde.org/"&gt;Konsole&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;For additional reading I recommend the &lt;a href="http://www.cl.cam.ac.uk/~mgk25/unicode.html"&gt;UTF-8 and Unicode FAQ for Unix/Linux&lt;/a&gt;, the &lt;a href="http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/l10n.html"&gt;Localization - I18N/L10N Usage and Setup&lt;/a&gt; chapter of the FreeBSD Handbook, &lt;a href="http://www.gentoo.org/doc/en/utf-8.xml"&gt;Using UTF-8 with Gentoo&lt;/a&gt;, and the &lt;a href="http://www.gentoo.org/doc/en/guide-localization.xml"&gt;Gentoo Linux Localization Guide&lt;/a&gt;.&lt;/p&gt;</content><category term="sysadmin"></category><category term="freebsd"></category><category term="unicode"></category></entry><entry><title>Upgrading PostgreSQL on FreeBSD</title><link href="https://www.b1c1l1.com/blog/2011/01/01/upgrading-postgresql-on-freebsd/" rel="alternate"></link><published>2011-01-01T23:04:01-08:00</published><updated>2011-01-01T23:04:01-08:00</updated><author><name>Benjamin Lee</name></author><id>tag:www.b1c1l1.com,2011-01-01:/blog/2011/01/01/upgrading-postgresql-on-freebsd/</id><summary type="html">&lt;p&gt;The default version of PostgreSQL on FreeBSD has been changed from 8.2 to 8.4. Upgrading PostgreSQL requires dumping and restoring the database.&lt;/p&gt;</summary><content type="html">&lt;p&gt;I decided to upgrade my &lt;a href="http://www.postgresql.org/"&gt;PostgreSQL&lt;/a&gt; database instances because the default version of PostgreSQL on FreeBSD has been changed from 8.2 to 8.4.  The internal data storage format changes in every major release of PostgreSQL, so upgrades require dumping and restoring the database.&lt;/p&gt;
&lt;p&gt;First, dump the existing PostgreSQL database.  It is essential that no changes are made to the database after it is dumped or data will be lost.  There are many ways to achieve this, such as using a firewall or modifying pg_hba.conf.  My preferred method is to start a temporary PostgreSQL instance on a non-standard port.&lt;/p&gt;
&lt;ol class="blocknumbers"&gt;
&lt;li&gt;&lt;p&gt;Stop PostgreSQL.&lt;/p&gt;&lt;pre&gt;sudo /usr/local/etc/rc.d/postgresql stop&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Start a temporary PostgreSQL instance on a non-standard port to dump the database.&lt;/p&gt;&lt;pre&gt;sudo -u pgsql -H pg_ctl start -D /usr/local/pgsql/data -o "-p 55555"&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use pg_dumpall(1) to dump the database from the temporary instance.&lt;/p&gt;&lt;pre&gt;pg_dumpall -U pgsql -p 55555 &amp;gt; pg_dumpall.`date +%Y%m%d%H%M`.sql&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Stop the temporary PostgreSQL instance.&lt;/p&gt;&lt;pre&gt;sudo -u pgsql -H pg_ctl stop -D /usr/local/pgsql/data&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Rename the PostgreSQL data directory, which will not be used by the new version of PostgreSQL.&lt;/p&gt;&lt;pre&gt;sudo mv -v /usr/local/pgsql /usr/local/pgsql.`date +%Y%m%d%H%M`&lt;/pre&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Next, upgrade the PostgreSQL ports.  It is necessary to define DISABLE_CONFLICTS because the CONFLICTS check does not account for the change in port origin and will cause the in-place upgrade to fail.&lt;/p&gt;
&lt;ol class="blocknumbers"&gt;
&lt;li&gt;&lt;p&gt;Upgrade the PostgreSQL client first because it is a dependency of the PostgreSQL server.&lt;/p&gt;&lt;pre&gt;sudo portupgrade -o databases/postgresql84-client -m DISABLE_CONFLICTS=yes "postgresql-client-*"&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Upgrade the PostgreSQL server.&lt;/p&gt;&lt;pre&gt;sudo portupgrade -o databases/postgresql84-server -m DISABLE_CONFLICTS=yes "postgresql-server-*"&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Rebuild all ports dependending on the PostgreSQL client in order to ensure dynamic linking consistency after the changes in shared library versions.&lt;/p&gt;&lt;pre&gt;sudo portupgrade -rf "postgresql-client-*"&lt;/pre&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Finally, set up the new PostgreSQL database.  As with the dump, it is essential to prevent access to database until it is fully restored, which I achieve by starting a temporary PostgreSQL instance on a non-standard port.&lt;/p&gt;
&lt;ol class="blocknumbers"&gt;
&lt;li&gt;&lt;p&gt;Initialize the new PostgreSQL database using initdb.&lt;/p&gt;&lt;pre&gt;sudo /usr/local/etc/rc.d/postgresql initdb&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Reinstall configuration files that are stored in the PostgreSQL data directory.  Note that PostgreSQL configuration options are frequently changed so any existing configuration files may require modifications in order to work with the new version.  Configuration files that are stored in the data directory include:&lt;/p&gt;&lt;ul class="bullets"&gt;&lt;li&gt;/usr/local/pgsql/data/pg_hba.conf&lt;/li&gt;&lt;li&gt;/usr/local/pgsql/data/postgresql.conf&lt;/li&gt;&lt;li&gt;/usr/local/pgsql/data/server.crt&lt;/li&gt;&lt;li&gt;/usr/local/pgsql/data/server.key&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Start a temporary PostgreSQL instance on a non-standard port to restore the database.&lt;/p&gt;&lt;pre&gt;sudo -u pgsql -H pg_ctl start -D /usr/local/pgsql/data -o "-p 55555"&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use psql(1) to restore the database dump to the temporary instance.&lt;/p&gt;&lt;pre&gt;psql -U pgsql -p 55555 -d postgres -f pg_dumpall.201101012028.sql&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Stop the temporary PostgreSQL instance.&lt;/p&gt;&lt;pre&gt;sudo -u pgsql -H pg_ctl stop -D /usr/local/pgsql/data&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Start PostgreSQL.&lt;/p&gt;&lt;pre&gt;sudo /usr/local/etc/rc.d/postgresql start&lt;/pre&gt;&lt;/li&gt;
&lt;/ol&gt;</content><category term="sysadmin"></category><category term="freebsd"></category><category term="postgresql"></category></entry></feed>