More sensible header structure. Cute cow at the bottom
This commit is contained in:
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
<!--# include file="include/top.html" -->
|
<!--# include file="include/top.html" -->
|
||||||
|
|
||||||
<h3>The Players</h3>
|
<h2>The Players</h2>
|
||||||
|
|
||||||
<p>I’ll be referring to 3 hosts:</p>
|
<p>I’ll be referring to 3 hosts:</p>
|
||||||
|
|
||||||
@@ -13,7 +13,7 @@
|
|||||||
<li>C: The client.</li>
|
<li>C: The client.</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<h3>Configuring B</h3>
|
<h2>Configuring B</h2>
|
||||||
|
|
||||||
<p>Some sshd configuration needs to be done on B before any of this will work. In the sshd_config file (/etc/ssh/sshd_config on Debian):</p>
|
<p>Some sshd configuration needs to be done on B before any of this will work. In the sshd_config file (/etc/ssh/sshd_config on Debian):</p>
|
||||||
|
|
||||||
@@ -23,7 +23,7 @@ GatewayPorts yes
|
|||||||
|
|
||||||
<p>Remember to restart sshd after making changes (/etc/init.d/ssh restart).</p>
|
<p>Remember to restart sshd after making changes (/etc/init.d/ssh restart).</p>
|
||||||
|
|
||||||
<h3>Building the Tunnel</h3>
|
<h2>Building the Tunnel</h2>
|
||||||
|
|
||||||
<p>On A, run:</p>
|
<p>On A, run:</p>
|
||||||
|
|
||||||
@@ -39,7 +39,7 @@ GatewayPorts yes
|
|||||||
|
|
||||||
<p>As with all shell commands, put a “&” on the end to run it in the background.</p>
|
<p>As with all shell commands, put a “&” on the end to run it in the background.</p>
|
||||||
|
|
||||||
<h3>Tunnelling FTP</h3>
|
<h2>Tunnelling FTP</h2>
|
||||||
|
|
||||||
<p>Due to a trick in the FTP protocol, you can use this tunnelling arrangement but have FTP data connections go directly from A to C, without touching B. This only works with so-called “active” FTP (using the PORT command instead of PASV). C must also be unfirewalled for this to work.</p>
|
<p>Due to a trick in the FTP protocol, you can use this tunnelling arrangement but have FTP data connections go directly from A to C, without touching B. This only works with so-called “active” FTP (using the PORT command instead of PASV). C must also be unfirewalled for this to work.</p>
|
||||||
|
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ SHOW DATABASES;
|
|||||||
<pre><code>SHOW DATABASES;
|
<pre><code>SHOW DATABASES;
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<h3>The AUTO_INCREMENT problem</h3>
|
<h2>The AUTO_INCREMENT problem</h2>
|
||||||
|
|
||||||
<p>AUTO_INCREMENT-type columns get used in just about every MySQL table. They’re a quick way to build primary keys without thinking. However, there are obvious problems in a multi-master setup (if inserts happen on both servers at the same time, they’ll both get the same ID). The official MySQL solution (start the IDs on both servers at numbers significantly different from each other) is a nasty hack.</p>
|
<p>AUTO_INCREMENT-type columns get used in just about every MySQL table. They’re a quick way to build primary keys without thinking. However, there are obvious problems in a multi-master setup (if inserts happen on both servers at the same time, they’ll both get the same ID). The official MySQL solution (start the IDs on both servers at numbers significantly different from each other) is a nasty hack.</p>
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<!--# set var="title" value="Rebooting Linux when it doesn’t feel like it" -->
|
<!--# set var="title" value="Rebooting Linux when it doesn't feel like it" -->
|
||||||
<!--# set var="date" value="2006-02-02" -->
|
<!--# set var="date" value="2006-02-02" -->
|
||||||
|
|
||||||
<!--# include file="include/top.html" -->
|
<!--# include file="include/top.html" -->
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ Yes? <strong>bonding:802.3ad</strong>. No? <strong>bonding:active-backup</strong
|
|||||||
Yes? <strong>bonding:balance-alb</strong>. No? <strong>bonding:active-backup</strong>.</li>
|
Yes? <strong>bonding:balance-alb</strong>. No? <strong>bonding:active-backup</strong>.</li>
|
||||||
</ol>
|
</ol>
|
||||||
|
|
||||||
<h3>STP</h3>
|
<h2>STP</h2>
|
||||||
|
|
||||||
<p>This bonding method actually uses Linux’s support for interface bridging. If a bridge is set up between two interfaces connected to the same network and spanning tree protocol is activated, one interface will be put into blocking state and won’t pass traffic. This doesn’t aggregate bandwidth between interfaces when both are up, but it has the interesting effect of allowing the server to bridge traffic between the switches if there are no other available connections. Special configuration at the switches is required to prevent it from being used as a link under normal circumstances.</p>
|
<p>This bonding method actually uses Linux’s support for interface bridging. If a bridge is set up between two interfaces connected to the same network and spanning tree protocol is activated, one interface will be put into blocking state and won’t pass traffic. This doesn’t aggregate bandwidth between interfaces when both are up, but it has the interesting effect of allowing the server to bridge traffic between the switches if there are no other available connections. Special configuration at the switches is required to prevent it from being used as a link under normal circumstances.</p>
|
||||||
|
|
||||||
@@ -66,7 +66,7 @@ brctl showstp br0
|
|||||||
|
|
||||||
<p>One side of one interface should be blocking.</p>
|
<p>One side of one interface should be blocking.</p>
|
||||||
|
|
||||||
<h3>bonding</h3>
|
<h2>bonding</h2>
|
||||||
|
|
||||||
<p>For any of the bonding methods, you’ll need the ifenslave program. In Debian:</p>
|
<p>For any of the bonding methods, you’ll need the ifenslave program. In Debian:</p>
|
||||||
|
|
||||||
@@ -91,7 +91,7 @@ down ifenslave -d bond0 eth0 eth1
|
|||||||
<pre><code>ifup bond0
|
<pre><code>ifup bond0
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<h3>bonding:active-backup</h3>
|
<h2>bonding:active-backup</h2>
|
||||||
|
|
||||||
<p>This bonding mode keeps one interface completely blocked (including not sending ARP replies out it), using it strictly as a backup.</p>
|
<p>This bonding mode keeps one interface completely blocked (including not sending ARP replies out it), using it strictly as a backup.</p>
|
||||||
|
|
||||||
@@ -102,7 +102,7 @@ down ifenslave -d bond0 eth0 eth1
|
|||||||
|
|
||||||
<p>Follow the general bonding instructions above, and you’re all set!</p>
|
<p>Follow the general bonding instructions above, and you’re all set!</p>
|
||||||
|
|
||||||
<h3>bonding:802.3ad</h3>
|
<h2>bonding:802.3ad</h2>
|
||||||
|
|
||||||
<p>This bonding mode uses the standardized IEEE 802.3ad bonding method, with a protocol (LACP) for both sides to agree on bonding information. All links must be the same speed and duplex. The balancing method between links is determined by each end; a single connection will only go over one link, and sometimes traffic with a single (ethernet-level) peer will use a single link as well.</p>
|
<p>This bonding mode uses the standardized IEEE 802.3ad bonding method, with a protocol (LACP) for both sides to agree on bonding information. All links must be the same speed and duplex. The balancing method between links is determined by each end; a single connection will only go over one link, and sometimes traffic with a single (ethernet-level) peer will use a single link as well.</p>
|
||||||
|
|
||||||
@@ -127,7 +127,7 @@ end
|
|||||||
|
|
||||||
<p>Then follow the general bonding instructions.</p>
|
<p>Then follow the general bonding instructions.</p>
|
||||||
|
|
||||||
<h3>bonding:balance-alb</h3>
|
<h2>bonding:balance-alb</h2>
|
||||||
|
|
||||||
<p>This bonding mode balances outgoing traffic accoridng to interface speed and usage. It intercepts and rewrites outgoing ARP replies to make them come from different physical interfaces, tricking the network fabric into balancing incoming traffic as well.</p>
|
<p>This bonding mode balances outgoing traffic accoridng to interface speed and usage. It intercepts and rewrites outgoing ARP replies to make them come from different physical interfaces, tricking the network fabric into balancing incoming traffic as well.</p>
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
<p>This post is going to stray a bit from my usual geeky fare. I’m being asking far too much to help sort out haphazard home network designs that are causing real problems for their users. I decided to collect all the answers that I’ve given together in a single place that I can point to when asked.</p>
|
<p>This post is going to stray a bit from my usual geeky fare. I’m being asking far too much to help sort out haphazard home network designs that are causing real problems for their users. I decided to collect all the answers that I’ve given together in a single place that I can point to when asked.</p>
|
||||||
|
|
||||||
<h3>General Principles</h3>
|
<h2>General Principles</h2>
|
||||||
|
|
||||||
<p>Simplicity</p>
|
<p>Simplicity</p>
|
||||||
|
|
||||||
@@ -19,7 +19,7 @@
|
|||||||
<p>A Cisco Aironet is going to crash less than a Linksys access point. A Cisco switch is going to provide better throughput than a NetGear one. This isn’t a hard-and-fast rule; there are certainly decent, cheap network devices out there. However, generally, if a device has a plastic case and an external power supply and you’ve got more than 3 people depending on it, you’re going to regret the decision.</p>
|
<p>A Cisco Aironet is going to crash less than a Linksys access point. A Cisco switch is going to provide better throughput than a NetGear one. This isn’t a hard-and-fast rule; there are certainly decent, cheap network devices out there. However, generally, if a device has a plastic case and an external power supply and you’ve got more than 3 people depending on it, you’re going to regret the decision.</p>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
|
|
||||||
<h3>Sorting out the devices</h3>
|
<h2>Sorting out the devices</h2>
|
||||||
|
|
||||||
<ol>
|
<ol>
|
||||||
<li>Diagram your network. Knowing what you have and how it’s all connected together is a critical first step toward fixing any of it. A complete diagram looks like:<br>
|
<li>Diagram your network. Knowing what you have and how it’s all connected together is a critical first step toward fixing any of it. A complete diagram looks like:<br>
|
||||||
@@ -38,7 +38,7 @@ sudo dhclient eth0
|
|||||||
<p>You should see one or more lines starting with DHCPOFFER and telling you where the offer came from. If you see more than one source of offers, you need to eliminate extra DHCP servers.</p></li>
|
<p>You should see one or more lines starting with DHCPOFFER and telling you where the offer came from. If you see more than one source of offers, you need to eliminate extra DHCP servers.</p></li>
|
||||||
</ol>
|
</ol>
|
||||||
|
|
||||||
<h3>Troubleshooting slowness</h3>
|
<h2>Troubleshooting slowness</h2>
|
||||||
|
|
||||||
<p>By far the most common network issue seems to be nebulous “slowness”. We’ll try to eliminate possibilities one by one.</p>
|
<p>By far the most common network issue seems to be nebulous “slowness”. We’ll try to eliminate possibilities one by one.</p>
|
||||||
|
|
||||||
@@ -68,11 +68,11 @@ sudo dhclient eth0
|
|||||||
<p>You’ll want to make the window a bit bigger. This application gives you real time timing data following the route from your network to firestuff.org. Watch the average times and loss percentages. Nothing above 0% is really acceptable loss; your ISP will probably claim that it is, but they’re lying. Remember that the numbers are cumulative; if hop 3 is dropping packets, those drops will effect hop 3 and everything beyond it. However, it’s really hop 3’s problem, and if hop 6 has a problem, it’ll be hard to see until you get the closer issue cleared up.</p></li>
|
<p>You’ll want to make the window a bit bigger. This application gives you real time timing data following the route from your network to firestuff.org. Watch the average times and loss percentages. Nothing above 0% is really acceptable loss; your ISP will probably claim that it is, but they’re lying. Remember that the numbers are cumulative; if hop 3 is dropping packets, those drops will effect hop 3 and everything beyond it. However, it’s really hop 3’s problem, and if hop 6 has a problem, it’ll be hard to see until you get the closer issue cleared up.</p></li>
|
||||||
</ol>
|
</ol>
|
||||||
|
|
||||||
<h3>Troubleshooting idle disconnects</h3>
|
<h2>Troubleshooting idle disconnects</h2>
|
||||||
|
|
||||||
<p>Do you have long-running connections (SSH, telnet, MySQL, etc.) that get disconnected when they’re not doing anything? It’s your NAT device’s fault. Period. If it doesn’t have a setting to change the maximum idle time for a connection, throw it out and buy one that does.</p>
|
<p>Do you have long-running connections (SSH, telnet, MySQL, etc.) that get disconnected when they’re not doing anything? It’s your NAT device’s fault. Period. If it doesn’t have a setting to change the maximum idle time for a connection, throw it out and buy one that does.</p>
|
||||||
|
|
||||||
<h3>Troubleshooting wireless problems</h3>
|
<h2>Troubleshooting wireless problems</h2>
|
||||||
|
|
||||||
<ol>
|
<ol>
|
||||||
<li>Does rebooting your wireless router/access point fix it? Throw it out and buy a real one (I kept buying new Linksys/NetGear products until I gave up and started buying Cisco. Oddly, since then, things work).</li>
|
<li>Does rebooting your wireless router/access point fix it? Throw it out and buy a real one (I kept buying new Linksys/NetGear products until I gave up and started buying Cisco. Oddly, since then, things work).</li>
|
||||||
|
|||||||
@@ -5,39 +5,39 @@
|
|||||||
|
|
||||||
<p>After getting the Internet connection all tuned up, it's time to talk network speed.</p>
|
<p>After getting the Internet connection all tuned up, it's time to talk network speed.</p>
|
||||||
|
|
||||||
<h3>How fast do you need to go?</h3>
|
<h2>How fast do you need to go?</h2>
|
||||||
|
|
||||||
<p>Talking about gigabit speeds around the office drew some incredulity. Most users seem to be used to talking about Internet connection speeds in the sub-10mbit range, so a 10mbit hub (which my new apartment came prewired with) and 802.11b (6mbit/s TCP) or at least 802.11g (~30mbit/s TCP) will pretty much suffice. Political arguments about the mess that is US last-mile Internet connections aside, however, there are expensive options at higher speeds. Some areas have FiOS (though Verizon has apparently stopped rolling it out), and Comcast has a 50mbit/s "Extreme" plan in my area for $115/month. DOCSIS 3 supports up to ~160mbit/s link speed. Broadband speeds don't obey Moore's law (mostly due to the enormous infrastructure investment required to deploy new tech), but we'll still probably see cable plans breaking the 100mbit/s barrier in 3 or 4 years max. In short, it's a gigabit ethernet (~700mbit/s in real life) and 802.11n (~150mbit/s with today's gear) world for the short- to medium-term.</p>
|
<p>Talking about gigabit speeds around the office drew some incredulity. Most users seem to be used to talking about Internet connection speeds in the sub-10mbit range, so a 10mbit hub (which my new apartment came prewired with) and 802.11b (6mbit/s TCP) or at least 802.11g (~30mbit/s TCP) will pretty much suffice. Political arguments about the mess that is US last-mile Internet connections aside, however, there are expensive options at higher speeds. Some areas have FiOS (though Verizon has apparently stopped rolling it out), and Comcast has a 50mbit/s "Extreme" plan in my area for $115/month. DOCSIS 3 supports up to ~160mbit/s link speed. Broadband speeds don't obey Moore's law (mostly due to the enormous infrastructure investment required to deploy new tech), but we'll still probably see cable plans breaking the 100mbit/s barrier in 3 or 4 years max. In short, it's a gigabit ethernet (~700mbit/s in real life) and 802.11n (~150mbit/s with today's gear) world for the short- to medium-term.</p>
|
||||||
|
|
||||||
<h3>Defining your users</h3>
|
<h2>Defining your users</h2>
|
||||||
|
|
||||||
<p>My use cases for wireless at home divide pretty neatly into two categories: high-bandwidth, low-latency streaming to fixed points (Mac Minis hooked up to my TVs), and bursty-bandwidth, can-survive-momentary-latency clients that move around a lot (laptop, cellphone, iPad). I'd like both to be able to max out my Internet connection, but the video streaming needs to be able to do better inside my network (streaming from my iMac). This may get murkier once Apple get iTunes streaming to the iPad working.</p>
|
<p>My use cases for wireless at home divide pretty neatly into two categories: high-bandwidth, low-latency streaming to fixed points (Mac Minis hooked up to my TVs), and bursty-bandwidth, can-survive-momentary-latency clients that move around a lot (laptop, cellphone, iPad). I'd like both to be able to max out my Internet connection, but the video streaming needs to be able to do better inside my network (streaming from my iMac). This may get murkier once Apple get iTunes streaming to the iPad working.</p>
|
||||||
|
|
||||||
<h3>The first hop</h3>
|
<h2>The first hop</h2>
|
||||||
|
|
||||||
<p>No amount of optimization on the wireless side is going to help if the cable modem to router hop can't push the full speed of the 'net connection (this presumes that they're two different devices for you). First, both should support GigE (I have a Motorola SB6120 and a D-Link DIR-855). It's harder than it should be to verify the connection speed between these two; in the end, I had to force the link on the router end to 1000mbit/s-only, then make sure it still connected.</p>
|
<p>No amount of optimization on the wireless side is going to help if the cable modem to router hop can't push the full speed of the 'net connection (this presumes that they're two different devices for you). First, both should support GigE (I have a Motorola SB6120 and a D-Link DIR-855). It's harder than it should be to verify the connection speed between these two; in the end, I had to force the link on the router end to 1000mbit/s-only, then make sure it still connected.</p>
|
||||||
|
|
||||||
<p>My apartment isn't wired ideally, so the cable modem and router are in different places. The apartment has ethernet throughout, but it's only wired with 2 pairs (out of the 4 pairs in an RJ45 connector); that's only sufficient for 100mbit/s links. Kacirek brought over the toolkit and we appropriated some telephone wiring to serve as the extra two pairs, replacing the 10mbit hub with an ethernet coupler.</p>
|
<p>My apartment isn't wired ideally, so the cable modem and router are in different places. The apartment has ethernet throughout, but it's only wired with 2 pairs (out of the 4 pairs in an RJ45 connector); that's only sufficient for 100mbit/s links. Kacirek brought over the toolkit and we appropriated some telephone wiring to serve as the extra two pairs, replacing the 10mbit hub with an ethernet coupler.</p>
|
||||||
|
|
||||||
<h3>Going N-only</h3>
|
<h2>Going N-only</h2>
|
||||||
|
|
||||||
<p>The 802.11b to 802.11g migration was a mess; networks effectively dropped back to all-B in the presence of even a single B device. G to N isn't as bad, but it's not great; 802.11 continues to accumulate backwards-compatibility hacks all over the place. However, I was surprised to find that every device except my old T60 supports N, including my Nexus One. It didn't ship with the support, and Google never indicated that an upgrade to it was forthcoming, but it must have snuck out with a firmware upgrade somewhere. After digging out an old 802.11n mini-PCI card that I bought years ago and upgrading the T60, I was able to switch from G/N to just N. This is probably a significant win, if you can manage to upgrade all your devices. If not, confining the older ones to 2.4GHz (leaving 5GHz to pure-N, rather than A/N) is probably your best bet.</p>
|
<p>The 802.11b to 802.11g migration was a mess; networks effectively dropped back to all-B in the presence of even a single B device. G to N isn't as bad, but it's not great; 802.11 continues to accumulate backwards-compatibility hacks all over the place. However, I was surprised to find that every device except my old T60 supports N, including my Nexus One. It didn't ship with the support, and Google never indicated that an upgrade to it was forthcoming, but it must have snuck out with a firmware upgrade somewhere. After digging out an old 802.11n mini-PCI card that I bought years ago and upgrading the T60, I was able to switch from G/N to just N. This is probably a significant win, if you can manage to upgrade all your devices. If not, confining the older ones to 2.4GHz (leaving 5GHz to pure-N, rather than A/N) is probably your best bet.</p>
|
||||||
|
|
||||||
<h3>There's N, then there's N</h3>
|
<h2>There's N, then there's N</h2>
|
||||||
|
|
||||||
<p>802.11n has to be one of the most consumer-confusing specs ever. N works by using multiple antennas to build virtual "spatial streams". For example, radio one has antennas 1A and 1B; radio two has 2A, 2B and 2C. The silicon supports 2 spatial channels, which get built between, e.g. 1A and 2B, 1B and 2C. These spatial channels are treated as separate links, even though they're on the same frequency. There are 16 possible antenna/radio configurations and 30 antenna/radio/spatial channel configurations. The configurations are abbreviated AxB:C (A: transmit radios/antennas, B: receive radios/antennas, C: processor-supported spatial channels). The spec goes up to 4x4:4. Unfortunately, this means that 3-antenna systems aren't necessarily 3-stream (and most sold today aren't). You can't have more streams than your lowest radio/antenna count, and your maximum speed is determined by your number of streams and frequency width. N can use 20MHz or 40MHz of radio spectrum. The DIR-855 I bought seems to be either 2x3:2 or 3x3:2; 300mbit/s max at 40MHz. It seems to be impossible to buy 3- or 4-stream consumer gear at the moment (and you need client gear to support it, so it wouldn't be too useful).</p>
|
<p>802.11n has to be one of the most consumer-confusing specs ever. N works by using multiple antennas to build virtual "spatial streams". For example, radio one has antennas 1A and 1B; radio two has 2A, 2B and 2C. The silicon supports 2 spatial channels, which get built between, e.g. 1A and 2B, 1B and 2C. These spatial channels are treated as separate links, even though they're on the same frequency. There are 16 possible antenna/radio configurations and 30 antenna/radio/spatial channel configurations. The configurations are abbreviated AxB:C (A: transmit radios/antennas, B: receive radios/antennas, C: processor-supported spatial channels). The spec goes up to 4x4:4. Unfortunately, this means that 3-antenna systems aren't necessarily 3-stream (and most sold today aren't). You can't have more streams than your lowest radio/antenna count, and your maximum speed is determined by your number of streams and frequency width. N can use 20MHz or 40MHz of radio spectrum. The DIR-855 I bought seems to be either 2x3:2 or 3x3:2; 300mbit/s max at 40MHz. It seems to be impossible to buy 3- or 4-stream consumer gear at the moment (and you need client gear to support it, so it wouldn't be too useful).</p>
|
||||||
|
|
||||||
<h3>2.4GHz vs. 5GHz</h3>
|
<h2>2.4GHz vs. 5GHz</h2>
|
||||||
|
|
||||||
<p>802.11n makes the frequency choice even harder than it used to be. 2.4GHz is an overpopulated ghetto unless you live on double-digit acreage. It penetrates walls significantly better than 5GHz, but that's a blessing and a curse: you can use it from further away, but your neighbors interfere from further away. Even worse, at 40MHz, 802.11n takes 2 of the 3 non-overlapping 2.4GHz channels. That means that if you can see two or more neighboring access points, you're not getting full speed. The penetration advantages are significant, though: my iPad gets 6mbit/s link speed on 5GHz at the furthest point in my apartment from my access point. At 2.4GHz, it gets 26mbit/s.</p>
|
<p>802.11n makes the frequency choice even harder than it used to be. 2.4GHz is an overpopulated ghetto unless you live on double-digit acreage. It penetrates walls significantly better than 5GHz, but that's a blessing and a curse: you can use it from further away, but your neighbors interfere from further away. Even worse, at 40MHz, 802.11n takes 2 of the 3 non-overlapping 2.4GHz channels. That means that if you can see two or more neighboring access points, you're not getting full speed. The penetration advantages are significant, though: my iPad gets 6mbit/s link speed on 5GHz at the furthest point in my apartment from my access point. At 2.4GHz, it gets 26mbit/s.</p>
|
||||||
|
|
||||||
<p>Dual-band solutions help, but you have to be careful. Assign different SSIDs to your 2.4GHz and 5GHz networks, so you can force clients to one or the other. Put things like video streaming in 5GHz, where a neighbor download isn't likely to cause hiccups. Test your other devices at maximum range, and see whether you can live with the 5GHz signal level.</p>
|
<p>Dual-band solutions help, but you have to be careful. Assign different SSIDs to your 2.4GHz and 5GHz networks, so you can force clients to one or the other. Put things like video streaming in 5GHz, where a neighbor download isn't likely to cause hiccups. Test your other devices at maximum range, and see whether you can live with the 5GHz signal level.</p>
|
||||||
|
|
||||||
<h3>A little more range</h3>
|
<h2>A little more range</h2>
|
||||||
|
|
||||||
<p>If you'd like to squeak just a little more range out of your access point, either to be able to use 5GHz where you would've used 2.4GHz, or to be able to reach far-away spots with anything at all, consider replacement antennas. Higher-grade access points support them, and they'll buy you a little bit, though don't expect miracles. I picked up 3 of these, which help a bit without taking it to ridiculous extremes.</p>
|
<p>If you'd like to squeak just a little more range out of your access point, either to be able to use 5GHz where you would've used 2.4GHz, or to be able to reach far-away spots with anything at all, consider replacement antennas. Higher-grade access points support them, and they'll buy you a little bit, though don't expect miracles. I picked up 3 of these, which help a bit without taking it to ridiculous extremes.</p>
|
||||||
|
|
||||||
<h3>Other optimizations</h3>
|
<h2>Other optimizations</h2>
|
||||||
|
|
||||||
<p>Location, location, location: put your access point in the middle of your coverage area. It's the simplest thing you can do to get massive speed gains.</p>
|
<p>Location, location, location: put your access point in the middle of your coverage area. It's the simplest thing you can do to get massive speed gains.</p>
|
||||||
|
|
||||||
|
|||||||
@@ -3,11 +3,11 @@
|
|||||||
|
|
||||||
<!--# include file="include/top.html" -->
|
<!--# include file="include/top.html" -->
|
||||||
|
|
||||||
<h3>Choosing a platform</h3>
|
<h2>Choosing a platform</h2>
|
||||||
|
|
||||||
<p>There's no shortage of alternatives to the traditional cable box + TV model, from cable provider DVRs to <a href="http://www.tivo.com/">TiVo</a> (yes, people actually still own those) to more obscure offerings like <a href="http://www.myka.tv/">Myka</a>, or <a href="http://www.mythtv.org/">MythTV</a> running on your closest whitebox. However, if you want to combine easy content sourcing, central storage/management with streaming, a nice remote control interface and solid, attractive hardware, there's really only one option: for better or worse, Apple's <a href="http://www.apple.com/itunes/">iTunes</a>/<a href="http://en.wikipedia.org/wiki/Front_Row_(software%29">Front Row</a>.</p>
|
<p>There's no shortage of alternatives to the traditional cable box + TV model, from cable provider DVRs to <a href="http://www.tivo.com/">TiVo</a> (yes, people actually still own those) to more obscure offerings like <a href="http://www.myka.tv/">Myka</a>, or <a href="http://www.mythtv.org/">MythTV</a> running on your closest whitebox. However, if you want to combine easy content sourcing, central storage/management with streaming, a nice remote control interface and solid, attractive hardware, there's really only one option: for better or worse, Apple's <a href="http://www.apple.com/itunes/">iTunes</a>/<a href="http://en.wikipedia.org/wiki/Front_Row_(software%29">Front Row</a>.</p>
|
||||||
|
|
||||||
<h3>Electronics</h3>
|
<h2>Electronics</h2>
|
||||||
|
|
||||||
<p>I already had an iMac that had ended up at a common-area computer desk in my apartment. This seemed a reasonable choice for a media server, though I suppose I could've shot for something that had a concept of running headless (another <a href="http://www.apple.com/macmini/">Mac Mini</a>).</p>
|
<p>I already had an iMac that had ended up at a common-area computer desk in my apartment. This seemed a reasonable choice for a media server, though I suppose I could've shot for something that had a concept of running headless (another <a href="http://www.apple.com/macmini/">Mac Mini</a>).</p>
|
||||||
|
|
||||||
@@ -15,23 +15,23 @@
|
|||||||
|
|
||||||
<p>As actual displays, I went with <a href="http://www.samsung.com/us/consumer/tv-video/televisions/led-tv/UN40B7000WFUZA/index.idx?pagetype=prd_detail&returnurl=">LED-backlit Samsung LCDs</a>, for the lower power usage and the light weight for wall hanging. Add in <a href="http://www.monoprice.com/products/product.asp?c_id=102&cp_id=10246&cs_id=1024603&p_id=5994&seq=1&format=2">some</a> <a href="http://www.monoprice.com/products/product.asp?c_id=102&cp_id=10218&cs_id=1021802&p_id=5576&seq=1&format=2">cables</a> and we're good to go...except that it's all sitting on the floor.</p>
|
<p>As actual displays, I went with <a href="http://www.samsung.com/us/consumer/tv-video/televisions/led-tv/UN40B7000WFUZA/index.idx?pagetype=prd_detail&returnurl=">LED-backlit Samsung LCDs</a>, for the lower power usage and the light weight for wall hanging. Add in <a href="http://www.monoprice.com/products/product.asp?c_id=102&cp_id=10246&cs_id=1024603&p_id=5994&seq=1&format=2">some</a> <a href="http://www.monoprice.com/products/product.asp?c_id=102&cp_id=10218&cs_id=1021802&p_id=5576&seq=1&format=2">cables</a> and we're good to go...except that it's all sitting on the floor.</p>
|
||||||
|
|
||||||
<h3>Wall mounting</h3>
|
<h2>Wall mounting</h2>
|
||||||
|
|
||||||
<p>Fortunately, my two TVs were wall mount efforts #6 and 7 for Kacirek, so this went really smoothly. I picked up <a href="http://www.monoprice.com/products/product.asp?c_id=108&cp_id=10828&cs_id=1082812&p_id=5918&seq=1&format=2">wall mount kits</a> from Monoprice. In short: stud finder, level, pilot holes, lag bolts, bolts to the TV, hang, done. There are even nice <a href="http://www.amazon.com/gp/product/B000UWI2LC/ref=oss_product">wall mount kits for Mac Minis</a>, naturally at more than twice the price of the LCD mounts, since they count as "designer". The Mac Mini power adapter fits really nicely in a cable-management cutout at the back of the TV. Add in an extension cord and some cable management from Fry's, and voila:</p>
|
<p>Fortunately, my two TVs were wall mount efforts #6 and 7 for Kacirek, so this went really smoothly. I picked up <a href="http://www.monoprice.com/products/product.asp?c_id=108&cp_id=10828&cs_id=1082812&p_id=5918&seq=1&format=2">wall mount kits</a> from Monoprice. In short: stud finder, level, pilot holes, lag bolts, bolts to the TV, hang, done. There are even nice <a href="http://www.amazon.com/gp/product/B000UWI2LC/ref=oss_product">wall mount kits for Mac Minis</a>, naturally at more than twice the price of the LCD mounts, since they count as "designer". The Mac Mini power adapter fits really nicely in a cable-management cutout at the back of the TV. Add in an extension cord and some cable management from Fry's, and voila:</p>
|
||||||
|
|
||||||
<p>[images lost in Picasa shutdown]</p>
|
<p>[images lost in Picasa shutdown]</p>
|
||||||
|
|
||||||
<h3>Front Row love and hate</h3>
|
<h2>Front Row love and hate</h2>
|
||||||
|
|
||||||
<p>Front Row is, at times, awesome. It remembers pause position across different streaming clients. The interface is simple and useful. Over a fast network, seeking and fast-forward are lightning-quick. It doesn't let you set a default streaming source, but that only adds a couple of clicks.</p>
|
<p>Front Row is, at times, awesome. It remembers pause position across different streaming clients. The interface is simple and useful. Over a fast network, seeking and fast-forward are lightning-quick. It doesn't let you set a default streaming source, but that only adds a couple of clicks.</p>
|
||||||
|
|
||||||
<p>Sometimes, it's horribly frustrating. It hangs indefinitely and uninterruptably trying to load remote library contents. It forgets pause position, even on the same machine. None of these are repeatable, so trying to solve them seems nigh-impossible.</p>
|
<p>Sometimes, it's horribly frustrating. It hangs indefinitely and uninterruptably trying to load remote library contents. It forgets pause position, even on the same machine. None of these are repeatable, so trying to solve them seems nigh-impossible.</p>
|
||||||
|
|
||||||
<h3>Unofficial content</h3>
|
<h2>Unofficial content</h2>
|
||||||
|
|
||||||
<p>iTunes also doesn't want you using their fancy toys with torrented files; it won't let you add them to your library, and if you change the file type to work around that, it still won't stream them to remote clients. Fortunately, this is pretty simple to work around. You need <a href="http://www.apple.com/quicktime/pro/">Quicktime Pro</a>, which comes with Final Cut Studio, is cheap to buy separately, or can be obtained by whatever means you like. It hides in Utilities once installed, and is easy to confuse with Apple's stripped-down but base-install Quicktime Player. Follow steps 1-4 <a href="http://www.apple.com/quicktime/tutorials/hinttracks.html">here</a>, and your torrented content is now draggable into iTunes and streamable to Front Row clients. It doesn't re-encode unless you do steps 5-8, so it's fast and you don't lose quality.</p>
|
<p>iTunes also doesn't want you using their fancy toys with torrented files; it won't let you add them to your library, and if you change the file type to work around that, it still won't stream them to remote clients. Fortunately, this is pretty simple to work around. You need <a href="http://www.apple.com/quicktime/pro/">Quicktime Pro</a>, which comes with Final Cut Studio, is cheap to buy separately, or can be obtained by whatever means you like. It hides in Utilities once installed, and is easy to confuse with Apple's stripped-down but base-install Quicktime Player. Follow steps 1-4 <a href="http://www.apple.com/quicktime/tutorials/hinttracks.html">here</a>, and your torrented content is now draggable into iTunes and streamable to Front Row clients. It doesn't re-encode unless you do steps 5-8, so it's fast and you don't lose quality.</p>
|
||||||
|
|
||||||
<h3>Automatic wake-up</h3>
|
<h2>Automatic wake-up</h2>
|
||||||
|
|
||||||
<p>I also wanted waking up the Mini clients to automatically wake up the iMac file server, so I didn't have to leave it running all the time. Again, this isn't too hard. First, pick up <a href="http://www.bernhard-baehr.de/">SleepWatcher</a>, clearly written and packaged by someone who's never heard of dmg or a Makefile (but it works). Install <a href="http://gsd.di.uminho.pt/jpo/software/wakeonlan/">wakeonlan</a>, a tiny little PERL script that sends <a href="http://en.wikipedia.org/wiki/Wake-on-LAN">Wake-on-LAN</a> magic packets. Then, add something to /etc/rc.wakeup like:</p>
|
<p>I also wanted waking up the Mini clients to automatically wake up the iMac file server, so I didn't have to leave it running all the time. Again, this isn't too hard. First, pick up <a href="http://www.bernhard-baehr.de/">SleepWatcher</a>, clearly written and packaged by someone who's never heard of dmg or a Makefile (but it works). Install <a href="http://gsd.di.uminho.pt/jpo/software/wakeonlan/">wakeonlan</a>, a tiny little PERL script that sends <a href="http://en.wikipedia.org/wiki/Wake-on-LAN">Wake-on-LAN</a> magic packets. Then, add something to /etc/rc.wakeup like:</p>
|
||||||
|
|
||||||
@@ -45,7 +45,7 @@ done
|
|||||||
|
|
||||||
<p>Your path to wakeonlan, MAC address (of your fileserver) and packet count (and time) required for your network interface to come online may vary.</p>
|
<p>Your path to wakeonlan, MAC address (of your fileserver) and packet count (and time) required for your network interface to come online may vary.</p>
|
||||||
|
|
||||||
<h3>Hello, iPad?</h3>
|
<h2>Hello, iPad?</h2>
|
||||||
|
|
||||||
<p>It would be really great to be able to pull a Minority Report-style video transfer, moving streaming video seamlessly from a TV to the iPad and walking away with it. This is a pipe dream, however, until Apple decides to actually support streaming on the iPad. Seriously, Apple, I have to plug this thing in and copy the whole video to it to watch it?</p>
|
<p>It would be really great to be able to pull a Minority Report-style video transfer, moving streaming video seamlessly from a TV to the iPad and walking away with it. This is a pipe dream, however, until Apple decides to actually support streaming on the iPad. Seriously, Apple, I have to plug this thing in and copy the whole video to it to watch it?</p>
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
<p>I’ll be showing observed behavior through strace and tcpdump output.</p>
|
<p>I’ll be showing observed behavior through strace and tcpdump output.</p>
|
||||||
|
|
||||||
<h3>Setup</h3>
|
<h2>Setup</h2>
|
||||||
|
|
||||||
<p>Our test environment starts with two sockets connected to each other. There’s also a listening socket, only used to accept the initial connection, and an epoll fd. Both of the connected sockets are added to the epoll watch set, with most possible level-triggered flags enabled.</p>
|
<p>Our test environment starts with two sockets connected to each other. There’s also a listening socket, only used to accept the initial connection, and an epoll fd. Both of the connected sockets are added to the epoll watch set, with most possible level-triggered flags enabled.</p>
|
||||||
|
|
||||||
@@ -39,7 +39,7 @@ epoll_wait(3, {{EPOLLOUT, {u32=5, u64=5}}, {EPOLLOUT, {u32=6, u64=6}}}, 8, 0) =
|
|||||||
|
|
||||||
<p>We now have two file descriptors, 5 and 6, that are opposite ends of the same TCP connection. They’re both in the epoll set of epoll file descriptor 3. They’re both signaling writability (EPOLLOUT), and nothing else. All is as expected.</p>
|
<p>We now have two file descriptors, 5 and 6, that are opposite ends of the same TCP connection. They’re both in the epoll set of epoll file descriptor 3. They’re both signaling writability (EPOLLOUT), and nothing else. All is as expected.</p>
|
||||||
|
|
||||||
<h3>shutdown(SHUT_RD)</h3>
|
<h2>shutdown(SHUT_RD)</h2>
|
||||||
|
|
||||||
<p>Now let’s call shutdown(5, SHUT_RD).</p>
|
<p>Now let’s call shutdown(5, SHUT_RD).</p>
|
||||||
|
|
||||||
@@ -68,7 +68,7 @@ epoll_wait(3, {{EPOLLIN|EPOLLOUT|EPOLLRDHUP, {u32=6, u64=6}}}, 8, 0) = 1
|
|||||||
|
|
||||||
<p>Side note: notice that close(5) causes automatic removal of that socket from the epoll set. This is handy, but see dup() below.</p>
|
<p>Side note: notice that close(5) causes automatic removal of that socket from the epoll set. This is handy, but see dup() below.</p>
|
||||||
|
|
||||||
<h3>shutdown(SHUT_WR)</h3>
|
<h2>shutdown(SHUT_WR)</h2>
|
||||||
|
|
||||||
<p>Let’s rewind and test with SHUT_WR (write).</p>
|
<p>Let’s rewind and test with SHUT_WR (write).</p>
|
||||||
|
|
||||||
@@ -103,7 +103,7 @@ epoll_wait(3, {{EPOLLIN|EPOLLOUT|EPOLLERR|EPOLLHUP|EPOLLRDHUP, {u32=6, u64=6}}},
|
|||||||
|
|
||||||
<p>The only oddity here is that calling close(5) doesn’t change any of the epoll status flags for fd 6. Once you attempt to write to fd 6, however, every flag on the planet starts firing, including EPOLLERR and EPOLLHUP.</p>
|
<p>The only oddity here is that calling close(5) doesn’t change any of the epoll status flags for fd 6. Once you attempt to write to fd 6, however, every flag on the planet starts firing, including EPOLLERR and EPOLLHUP.</p>
|
||||||
|
|
||||||
<h3>dup()</h3>
|
<h2>dup()</h2>
|
||||||
|
|
||||||
<p>Rewinding to our setup state again, let’s look at dup().</p>
|
<p>Rewinding to our setup state again, let’s look at dup().</p>
|
||||||
|
|
||||||
@@ -134,7 +134,7 @@ epoll_wait(3, {{EPOLLIN|EPOLLOUT|EPOLLRDHUP, {u32=6, u64=6}}}, 8, 0) = 1
|
|||||||
|
|
||||||
<p>Here’s crazy town, though. close(5) doesn’t remove it from the epoll set. epoll is waiting for the underlying socket to close, and fd 7’s existence is keeping it alive. Trying to remove fd 5 from the epoll set also fails. The only way to get rid of it seems to be to close(7), which removes both from the set and causes fd 6 to signal EPOLLIN and EPOLLRDHUP.</p>
|
<p>Here’s crazy town, though. close(5) doesn’t remove it from the epoll set. epoll is waiting for the underlying socket to close, and fd 7’s existence is keeping it alive. Trying to remove fd 5 from the epoll set also fails. The only way to get rid of it seems to be to close(7), which removes both from the set and causes fd 6 to signal EPOLLIN and EPOLLRDHUP.</p>
|
||||||
|
|
||||||
<h3>shutdown(SHUT_RD) + dup()</h3>
|
<h2>shutdown(SHUT_RD) + dup()</h2>
|
||||||
|
|
||||||
<pre><code>dup(5) = 7
|
<pre><code>dup(5) = 7
|
||||||
epoll_ctl(3, EPOLL_CTL_ADD, 7, {EPOLLIN|EPOLLOUT|EPOLLERR|EPOLLHUP|EPOLLRDHUP, {u32=7, u64=7}}) = 0
|
epoll_ctl(3, EPOLL_CTL_ADD, 7, {EPOLLIN|EPOLLOUT|EPOLLERR|EPOLLHUP|EPOLLRDHUP, {u32=7, u64=7}}) = 0
|
||||||
@@ -147,7 +147,7 @@ epoll_wait(3, {{EPOLLIN|EPOLLOUT|EPOLLRDHUP, {u32=5, u64=5}}, {EPOLLOUT, {u32=6,
|
|||||||
|
|
||||||
<p>The takeaway here is that shutdown() operates on the underlying socket endpoint, not the file descriptor. Calling shutdown(7, SHUT_RD) causes both fd 5 and 7 to signal EPOLLIN and EPOLLRDHUP.</p>
|
<p>The takeaway here is that shutdown() operates on the underlying socket endpoint, not the file descriptor. Calling shutdown(7, SHUT_RD) causes both fd 5 and 7 to signal EPOLLIN and EPOLLRDHUP.</p>
|
||||||
|
|
||||||
<h3>shutdown(SHUT_WR) + dup()</h3>
|
<h2>shutdown(SHUT_WR) + dup()</h2>
|
||||||
|
|
||||||
<pre><code>dup(5) = 7
|
<pre><code>dup(5) = 7
|
||||||
epoll_ctl(3, EPOLL_CTL_ADD, 7, {EPOLLIN|EPOLLOUT|EPOLLERR|EPOLLHUP|EPOLLRDHUP, {u32=7, u64=7}}) = 0
|
epoll_ctl(3, EPOLL_CTL_ADD, 7, {EPOLLIN|EPOLLOUT|EPOLLERR|EPOLLHUP|EPOLLRDHUP, {u32=7, u64=7}}) = 0
|
||||||
@@ -164,7 +164,7 @@ epoll_wait(3, {{EPOLLOUT, {u32=5, u64=5}}, {EPOLLIN|EPOLLOUT|EPOLLRDHUP, {u32=6,
|
|||||||
|
|
||||||
<p>As expected, shutdown(7, SHUT_WR) causes fd 6 to signal EPOLLIN and EPOLLRDHUP.</p>
|
<p>As expected, shutdown(7, SHUT_WR) causes fd 6 to signal EPOLLIN and EPOLLRDHUP.</p>
|
||||||
|
|
||||||
<h3>Conclusions</h3>
|
<h2>Conclusions</h2>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li>If you’re using dup() and epoll, you need to call epoll_ctl(EPOLL_CTL_DEL) before calling close(). It’s hard to imagine getting sane behavior any other way. If you never use dup(), you can just call close().</li>
|
<li>If you’re using dup() and epoll, you need to call epoll_ctl(EPOLL_CTL_DEL) before calling close(). It’s hard to imagine getting sane behavior any other way. If you never use dup(), you can just call close().</li>
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
<p>Down another rabbit hole, this time into yet another seemingly simple problem: how do you turn a name into an address that you can connect() to without blocking your thread, in 2016. Let’s survey state of the world:</p>
|
<p>Down another rabbit hole, this time into yet another seemingly simple problem: how do you turn a name into an address that you can connect() to without blocking your thread, in 2016. Let’s survey state of the world:</p>
|
||||||
|
|
||||||
<h3><a href="http://man7.org/linux/man-pages/man3/getaddrinfo_a.3.html">getaddrinfo_a()</a></h3>
|
<h2><a href="http://man7.org/linux/man-pages/man3/getaddrinfo_a.3.html">getaddrinfo_a()</a></h2>
|
||||||
|
|
||||||
<p>Look, it’s exactly what we need! Just joking. It’s has the same resolution behavior as getaddrinfo, but:</p>
|
<p>Look, it’s exactly what we need! Just joking. It’s has the same resolution behavior as getaddrinfo, but:</p>
|
||||||
|
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
<li>It uses <a href="http://man7.org/linux/man-pages/man7/sigevent.7.html">sigevent</a> to notify completion. This gives you a choice between a signal and a new thread. I thought we were doing this to avoid having to create a new thread for each resolution?</li>
|
<li>It uses <a href="http://man7.org/linux/man-pages/man7/sigevent.7.html">sigevent</a> to notify completion. This gives you a choice between a signal and a new thread. I thought we were doing this to avoid having to create a new thread for each resolution?</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<h3><a href="http://www.gnu.org/software/adns/">libadns</a></h3>
|
<h2><a href="http://www.gnu.org/software/adns/">libadns</a></h2>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li>It’s GPLed. That’s cool, but it does limit options.</li>
|
<li>It’s GPLed. That’s cool, but it does limit options.</li>
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
<li>It will hand you file descriptors to block on, but you have to ask (using adns_beforeselect()). This is designed for poll(), but doesn’t work well with epoll; it doesn’t tell you when to add and remove fds, so you have to track them yourself (since you can’t iterate an epoll set), diff them since the last result, and change the epoll set. It’s a mess.</li>
|
<li>It will hand you file descriptors to block on, but you have to ask (using adns_beforeselect()). This is designed for poll(), but doesn’t work well with epoll; it doesn’t tell you when to add and remove fds, so you have to track them yourself (since you can’t iterate an epoll set), diff them since the last result, and change the epoll set. It’s a mess.</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<h3><a href="http://0pointer.de/lennart/projects/libasyncns/">libasyncns</a></h3>
|
<h2><a href="http://0pointer.de/lennart/projects/libasyncns/">libasyncns</a></h2>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li>It uses getaddrinfo() underneath, so you get standard behavior. Woo!</li>
|
<li>It uses getaddrinfo() underneath, so you get standard behavior. Woo!</li>
|
||||||
@@ -31,7 +31,7 @@
|
|||||||
<li>Its API isn’t too crazy, but you wouldn’t call it simple.</li>
|
<li>Its API isn’t too crazy, but you wouldn’t call it simple.</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<h3><a href="http://c-ares.haxx.se/">c-ares</a></h3>
|
<h2><a href="http://c-ares.haxx.se/">c-ares</a></h2>
|
||||||
|
|
||||||
<p>I failed to find docs for this, but I found a gist with an <a href="https://gist.github.com/mopemope/992777">example</a>. Looks like the API is designed for use with select(), though there’s a hook to get an fd when it’s created, so you might be able to associate it with a query, possibly unreliably. Again, you’d have to recreate getaddrinfo() behavior yourself. Also, this gem is at the top of the header:</p>
|
<p>I failed to find docs for this, but I found a gist with an <a href="https://gist.github.com/mopemope/992777">example</a>. Looks like the API is designed for use with select(), though there’s a hook to get an fd when it’s created, so you might be able to associate it with a query, possibly unreliably. Again, you’d have to recreate getaddrinfo() behavior yourself. Also, this gem is at the top of the header:</p>
|
||||||
|
|
||||||
@@ -46,7 +46,7 @@
|
|||||||
|
|
||||||
<p>So maybe not.</p>
|
<p>So maybe not.</p>
|
||||||
|
|
||||||
<h3>So now what?</h3>
|
<h2>So now what?</h2>
|
||||||
|
|
||||||
<p>Maybe we can build something. I really don’t need to write another DNS library in my lifetime (the c-ares <a href="http://c-ares.haxx.se/otherlibs.html">Other Libraries</a> page links to my previous one, humorously). Let’s see if we can scope some requirements:</p>
|
<p>Maybe we can build something. I really don’t need to write another DNS library in my lifetime (the c-ares <a href="http://c-ares.haxx.se/otherlibs.html">Other Libraries</a> page links to my previous one, humorously). Let’s see if we can scope some requirements:</p>
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
<p>Start with <a href="https://www.raspberrypi.org/downloads/raspbian/">Raspbian Lite</a>. NOOBS has an extra boot step, and Raspbian full version has a GUI and stuff like Wolfram Engine that you probably don’t want.</p>
|
<p>Start with <a href="https://www.raspberrypi.org/downloads/raspbian/">Raspbian Lite</a>. NOOBS has an extra boot step, and Raspbian full version has a GUI and stuff like Wolfram Engine that you probably don’t want.</p>
|
||||||
|
|
||||||
<h3>Log in</h3>
|
<h2>Log in</h2>
|
||||||
|
|
||||||
<p>Use console, or grab the IP from your router’s DHCP client list and:</p>
|
<p>Use console, or grab the IP from your router’s DHCP client list and:</p>
|
||||||
|
|
||||||
@@ -19,7 +19,7 @@
|
|||||||
# password "raspberry"
|
# password "raspberry"
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<h3>Expand filesystem</h3>
|
<h2>Expand filesystem</h2>
|
||||||
|
|
||||||
<pre><code>sudo raspi-config --expand-rootfs
|
<pre><code>sudo raspi-config --expand-rootfs
|
||||||
sudo reboot
|
sudo reboot
|
||||||
@@ -27,19 +27,19 @@ sudo reboot
|
|||||||
|
|
||||||
<p>Wait for reboot. Reconnect as above.</p>
|
<p>Wait for reboot. Reconnect as above.</p>
|
||||||
|
|
||||||
<h3>Update</h3>
|
<h2>Update</h2>
|
||||||
|
|
||||||
<pre><code>sudo apt-get -y update
|
<pre><code>sudo apt-get -y update
|
||||||
sudo apt-get -y dist-upgrade
|
sudo apt-get -y dist-upgrade
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<h3>Update firmware</h3>
|
<h2>Update firmware</h2>
|
||||||
|
|
||||||
<pre><code>sudo apt-get -y install rpi-update
|
<pre><code>sudo apt-get -y install rpi-update
|
||||||
sudo rpi-update
|
sudo rpi-update
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<h3>Enable overclock (optional)</h3>
|
<h2>Enable overclock (optional)</h2>
|
||||||
|
|
||||||
<p>Pis seem to be relatively stable overclocked, even without a heatsink.</p>
|
<p>Pis seem to be relatively stable overclocked, even without a heatsink.</p>
|
||||||
|
|
||||||
@@ -52,19 +52,19 @@ sudo rpi-update
|
|||||||
# Select "<No>"
|
# Select "<No>"
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<h3>Disable swap</h3>
|
<h2>Disable swap</h2>
|
||||||
|
|
||||||
<pre><code>sudo dphys-swapfile uninstall
|
<pre><code>sudo dphys-swapfile uninstall
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<h3>Create a new user</h3>
|
<h2>Create a new user</h2>
|
||||||
|
|
||||||
<pre><code>sudo adduser <username>
|
<pre><code>sudo adduser <username>
|
||||||
# Follow prompts
|
# Follow prompts
|
||||||
sudo usermod --append --groups sudo <username>
|
sudo usermod --append --groups sudo <username>
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<h3>SSH in as the new user</h3>
|
<h2>SSH in as the new user</h2>
|
||||||
|
|
||||||
<pre><code># ON YOUR PI
|
<pre><code># ON YOUR PI
|
||||||
# Find your Pi's current IP, you don't know it
|
# Find your Pi's current IP, you don't know it
|
||||||
@@ -82,7 +82,7 @@ scp ~/.ssh/id_ed25519.pub <username>@<ip>:.ssh/authorized_keys
|
|||||||
ssh <username>@<ip>
|
ssh <username>@<ip>
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<h3>Lock down sshd</h3>
|
<h2>Lock down sshd</h2>
|
||||||
|
|
||||||
<p>The SSH server has a lot of options turned on by default for compatibility with a wide range of clients. If you’re connecting only from modern machines, and you’ve gotten public key authentication working as described above (and tested it!), then you can turn off lots of the legacy options.</p>
|
<p>The SSH server has a lot of options turned on by default for compatibility with a wide range of clients. If you’re connecting only from modern machines, and you’ve gotten public key authentication working as described above (and tested it!), then you can turn off lots of the legacy options.</p>
|
||||||
|
|
||||||
@@ -121,7 +121,7 @@ END
|
|||||||
# Enter password for sudo
|
# Enter password for sudo
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<h3>Enable the hardware random number generator</h3>
|
<h2>Enable the hardware random number generator</h2>
|
||||||
|
|
||||||
<p>Note that hardware random number generators <a href="https://en.wikipedia.org/wiki/RdRand#Reception">are controversial</a>.</p>
|
<p>Note that hardware random number generators <a href="https://en.wikipedia.org/wiki/RdRand#Reception">are controversial</a>.</p>
|
||||||
|
|
||||||
@@ -130,7 +130,7 @@ echo bcm2835_rng | sudo tee --append /etc/modules
|
|||||||
sudo apt-get -y install rng-tools
|
sudo apt-get -y install rng-tools
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<h3>Enable the hardware watchdog</h3>
|
<h2>Enable the hardware watchdog</h2>
|
||||||
|
|
||||||
<p>This has false negatives (failures to reboot when it should) for me, but never false positives.</p>
|
<p>This has false negatives (failures to reboot when it should) for me, but never false positives.</p>
|
||||||
|
|
||||||
@@ -140,28 +140,28 @@ watchdog-device = /dev/watchdog
|
|||||||
END
|
END
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<h3>Enable automatic updates</h3>
|
<h2>Enable automatic updates</h2>
|
||||||
|
|
||||||
<pre><code>sudo apt-get -y install unattended-upgrades
|
<pre><code>sudo apt-get -y install unattended-upgrades
|
||||||
sudo dpkg-reconfigure -plow unattended-upgrades
|
sudo dpkg-reconfigure -plow unattended-upgrades
|
||||||
# Choose "<Yes>"
|
# Choose "<Yes>"
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<h3>Disable avahi</h3>
|
<h2>Disable avahi</h2>
|
||||||
|
|
||||||
<p>You didn’t need mdns, did you?</p>
|
<p>You didn’t need mdns, did you?</p>
|
||||||
|
|
||||||
<pre><code>sudo systemctl disable avahi-daemon.service
|
<pre><code>sudo systemctl disable avahi-daemon.service
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<h3>Disable triggerhappy</h3>
|
<h2>Disable triggerhappy</h2>
|
||||||
|
|
||||||
<p>You didn’t need volume buttons, did you?</p>
|
<p>You didn’t need volume buttons, did you?</p>
|
||||||
|
|
||||||
<pre><code>sudo systemctl disable triggerhappy.service
|
<pre><code>sudo systemctl disable triggerhappy.service
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<h3>Disable frequency scaling</h3>
|
<h2>Disable frequency scaling</h2>
|
||||||
|
|
||||||
<p>If you’re not planning to run on battery; this thing is slow enough anyway.</p>
|
<p>If you’re not planning to run on battery; this thing is slow enough anyway.</p>
|
||||||
|
|
||||||
@@ -171,7 +171,7 @@ GOVERNOR="performance"
|
|||||||
END
|
END
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<h3>Enable lldpd</h3>
|
<h2>Enable lldpd</h2>
|
||||||
|
|
||||||
<p>This allows you to observe network topology if you have managed switches.</p>
|
<p>This allows you to observe network topology if you have managed switches.</p>
|
||||||
|
|
||||||
@@ -181,28 +181,28 @@ DAEMON_ARGS="-c"
|
|||||||
END
|
END
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<h3>Remove the pi user</h3>
|
<h2>Remove the pi user</h2>
|
||||||
|
|
||||||
<p>Well-known username, well-known password, no thank you.</p>
|
<p>Well-known username, well-known password, no thank you.</p>
|
||||||
|
|
||||||
<pre><code>sudo deluser pi
|
<pre><code>sudo deluser pi
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<h3>Install busybox-syslogd</h3>
|
<h2>Install busybox-syslogd</h2>
|
||||||
|
|
||||||
<p>You give up persistent syslogs, but you reduce SD writes. You can still run “logread” to read logs since boot from RAM.</p>
|
<p>You give up persistent syslogs, but you reduce SD writes. You can still run “logread” to read logs since boot from RAM.</p>
|
||||||
|
|
||||||
<pre><code>sudo apt-get -y install busybox-syslogd
|
<pre><code>sudo apt-get -y install busybox-syslogd
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<h3>Reboot</h3>
|
<h2>Reboot</h2>
|
||||||
|
|
||||||
<p>Test that changes work, and have some (disabling auto-login) take effect.</p>
|
<p>Test that changes work, and have some (disabling auto-login) take effect.</p>
|
||||||
|
|
||||||
<pre><code>sudo reboot
|
<pre><code>sudo reboot
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<h3>After reboot</h3>
|
<h2>After reboot</h2>
|
||||||
|
|
||||||
<p>Note that ssh may scream “REMOTE HOST IDENTIFICATION HAS CHANGED!”; that’s a symptom of the sshd_config changes above. Just remove the line from the known_hosts file and reconnect.</p>
|
<p>Note that ssh may scream “REMOTE HOST IDENTIFICATION HAS CHANGED!”; that’s a symptom of the sshd_config changes above. Just remove the line from the known_hosts file and reconnect.</p>
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
<p>If you’ve got a router at the front of your network that supports static routes, though, you’ve got a conceptually simpler option: build a wireless client router. This is still a lot of moving parts and things to go wrong, but those things are going to be more debuggable when they do.</p>
|
<p>If you’ve got a router at the front of your network that supports static routes, though, you’ve got a conceptually simpler option: build a wireless client router. This is still a lot of moving parts and things to go wrong, but those things are going to be more debuggable when they do.</p>
|
||||||
|
|
||||||
<h3>Shopping list</h3>
|
<h2>Shopping list</h2>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="http://www.amazon.com/Raspberry-Pi-Model-Project-Board/dp/B00T2U7R7I">Raspberry Pi 2 Model B</a>. This probably works fine with a Pi 3; I just haven’t tested it.</li>
|
<li><a href="http://www.amazon.com/Raspberry-Pi-Model-Project-Board/dp/B00T2U7R7I">Raspberry Pi 2 Model B</a>. This probably works fine with a Pi 3; I just haven’t tested it.</li>
|
||||||
@@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
<p><a href="https://dev.firestuff.org/firestuff/2016-03-13-raspbian-setup-notes.html">Install and configure Raspbian Lite</a>. <a href="https://wiki.archlinux.org/index.php/WPA_supplicant">Get your device connected via WiFi</a>. (Side note: the ArchLinux wiki is really great).</p>
|
<p><a href="https://dev.firestuff.org/firestuff/2016-03-13-raspbian-setup-notes.html">Install and configure Raspbian Lite</a>. <a href="https://wiki.archlinux.org/index.php/WPA_supplicant">Get your device connected via WiFi</a>. (Side note: the ArchLinux wiki is really great).</p>
|
||||||
|
|
||||||
<h3>Assign a static IPv4 address</h3>
|
<h2>Assign a static IPv4 address</h2>
|
||||||
|
|
||||||
<p>Your wired side is going to need static addresses. These should be a different subnet than your existing private network. Strangely, in the new world, we configure static IPv4 addresses in /etc/dhcpcd.conf. Add a stanza that looks like:</p>
|
<p>Your wired side is going to need static addresses. These should be a different subnet than your existing private network. Strangely, in the new world, we configure static IPv4 addresses in /etc/dhcpcd.conf. Add a stanza that looks like:</p>
|
||||||
|
|
||||||
@@ -39,7 +39,7 @@
|
|||||||
noipv6rs
|
noipv6rs
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<h3>Assign a static IPv6 address</h3>
|
<h2>Assign a static IPv6 address</h2>
|
||||||
|
|
||||||
<p>You’ll need IPv6 addresses. These are going to be hard to keep in sync with IPv6 addresses on your main network; multi-level <a href="https://en.wikipedia.org/wiki/Prefix_delegation">prefix delegation</a> does not seem to be a thing yet, though that’s likely the future. In the meantime, set up unique local addresses so you can at least talk within your network. Go <a href="https://www.ultratools.com/tools/rangeGenerator">generate a unique local address block</a> to start with. Take the first address from that network (network::1) and configure it, this time in /etc/network/interfaces:</p>
|
<p>You’ll need IPv6 addresses. These are going to be hard to keep in sync with IPv6 addresses on your main network; multi-level <a href="https://en.wikipedia.org/wiki/Prefix_delegation">prefix delegation</a> does not seem to be a thing yet, though that’s likely the future. In the meantime, set up unique local addresses so you can at least talk within your network. Go <a href="https://www.ultratools.com/tools/rangeGenerator">generate a unique local address block</a> to start with. Take the first address from that network (network::1) and configure it, this time in /etc/network/interfaces:</p>
|
||||||
|
|
||||||
@@ -54,7 +54,7 @@ iface eth0 inet6 static
|
|||||||
|
|
||||||
<p>Really, don’t just use the address from this page; generate your own.</p>
|
<p>Really, don’t just use the address from this page; generate your own.</p>
|
||||||
|
|
||||||
<h3>Enable router advertisements</h3>
|
<h2>Enable router advertisements</h2>
|
||||||
|
|
||||||
<pre><code>sudo apt-get -y install radvd
|
<pre><code>sudo apt-get -y install radvd
|
||||||
</code></pre>
|
</code></pre>
|
||||||
@@ -73,7 +73,7 @@ iface eth0 inet6 static
|
|||||||
};
|
};
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<h3>Enable IP forwarding</h3>
|
<h2>Enable IP forwarding</h2>
|
||||||
|
|
||||||
<p>Edit /etc/sysctl.conf and uncomment the lines:</p>
|
<p>Edit /etc/sysctl.conf and uncomment the lines:</p>
|
||||||
|
|
||||||
@@ -82,7 +82,7 @@ iface eth0 inet6 static
|
|||||||
net.ipv6.conf.all.forwarding=1
|
net.ipv6.conf.all.forwarding=1
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<h3>Set up a DHCP server</h3>
|
<h2>Set up a DHCP server</h2>
|
||||||
|
|
||||||
<pre><code>sudo apt-get -y install isc-dhcp-server
|
<pre><code>sudo apt-get -y install isc-dhcp-server
|
||||||
</code></pre>
|
</code></pre>
|
||||||
@@ -102,7 +102,7 @@ subnet 10.167.0.0 netmask 255.255.0.0 {
|
|||||||
}
|
}
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<h3>Static IP and route</h3>
|
<h2>Static IP and route</h2>
|
||||||
|
|
||||||
<p>Now you need to assign a static IPv4 address to the wireless interface of the machine, and create static routes for both IPv4 and IPv6. You should do both of these in your primary router; Google for instructions. The examples below are for Cisco IOS, which is likely not very useful to you.</p>
|
<p>Now you need to assign a static IPv4 address to the wireless interface of the machine, and create static routes for both IPv4 and IPv6. You should do both of these in your primary router; Google for instructions. The examples below are for Cisco IOS, which is likely not very useful to you.</p>
|
||||||
|
|
||||||
@@ -115,11 +115,11 @@ ip route 10.167.0.0 255.255.0.0 10.66.0.3
|
|||||||
ipv6 route FD8B:CF21:31AC:69DF::/64 FD8B:CF21:31AC:A8CD:AD7F:4B19:EBD9:34CB
|
ipv6 route FD8B:CF21:31AC:69DF::/64 FD8B:CF21:31AC:A8CD:AD7F:4B19:EBD9:34CB
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<h3>Reboot</h3>
|
<h2>Reboot</h2>
|
||||||
|
|
||||||
<p>Reboot your RPi to pick up all these changes.</p>
|
<p>Reboot your RPi to pick up all these changes.</p>
|
||||||
|
|
||||||
<h3>Caveats</h3>
|
<h2>Caveats</h2>
|
||||||
|
|
||||||
<p>Because of the lack of multi-level prefix delegation, hosts behind your new router won’t have IPv6 connectivity to the world. Fingers crossed to fix this soon.</p>
|
<p>Because of the lack of multi-level prefix delegation, hosts behind your new router won’t have IPv6 connectivity to the world. Fingers crossed to fix this soon.</p>
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
<p>Notes from setting up a two-level (root and intermediate) CA using EC certs, combined from two decent sets of instructions <a href="https://jamielinux.com/docs/openssl-certificate-authority/introduction.html">here</a> and <a href="https://wiki.openssl.org/index.php/Command_Line_Elliptic_Curve_Operations">here</a>. This is the CliffsNotes version; see those two docs for more detail. XXXX is used as a placeholder here; search for it and replace.</p>
|
<p>Notes from setting up a two-level (root and intermediate) CA using EC certs, combined from two decent sets of instructions <a href="https://jamielinux.com/docs/openssl-certificate-authority/introduction.html">here</a> and <a href="https://wiki.openssl.org/index.php/Command_Line_Elliptic_Curve_Operations">here</a>. This is the CliffsNotes version; see those two docs for more detail. XXXX is used as a placeholder here; search for it and replace.</p>
|
||||||
|
|
||||||
<h3>Create directory structure</h3>
|
<h2>Create directory structure</h2>
|
||||||
|
|
||||||
<pre><code>mkdir ca
|
<pre><code>mkdir ca
|
||||||
cd ca
|
cd ca
|
||||||
@@ -133,21 +133,21 @@ extendedKeyUsage = critical, OCSPSigning
|
|||||||
END
|
END
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<h3>Create a root key</h3>
|
<h2>Create a root key</h2>
|
||||||
|
|
||||||
<pre><code>openssl ecparam -name secp384r1 -genkey | openssl ec -aes-256-cbc -out root/private/root.key.pem
|
<pre><code>openssl ecparam -name secp384r1 -genkey | openssl ec -aes-256-cbc -out root/private/root.key.pem
|
||||||
# Create strong root key password
|
# Create strong root key password
|
||||||
chmod 400 root/private/root.key.pem
|
chmod 400 root/private/root.key.pem
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<h3>Create a self-signed root cert</h3>
|
<h2>Create a self-signed root cert</h2>
|
||||||
|
|
||||||
<pre><code>openssl req -config openssl.cnf -key root/private/root.key.pem -new -extensions ext_root -out root/certs/root.cert.pem -x509 -subj '/C=US/ST=California/O=XXXX/OU=XXXX Certificate Authority/CN=XXXX Root CA' -days 7300
|
<pre><code>openssl req -config openssl.cnf -key root/private/root.key.pem -new -extensions ext_root -out root/certs/root.cert.pem -x509 -subj '/C=US/ST=California/O=XXXX/OU=XXXX Certificate Authority/CN=XXXX Root CA' -days 7300
|
||||||
# Enter root key password
|
# Enter root key password
|
||||||
chmod 444 root/certs/root.cert.pem
|
chmod 444 root/certs/root.cert.pem
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<h3>Verify root cert</h3>
|
<h2>Verify root cert</h2>
|
||||||
|
|
||||||
<pre><code>openssl x509 -noout -text -in root/certs/root.cert.pem
|
<pre><code>openssl x509 -noout -text -in root/certs/root.cert.pem
|
||||||
</code></pre>
|
</code></pre>
|
||||||
@@ -161,27 +161,27 @@ chmod 444 root/certs/root.cert.pem
|
|||||||
<li>CA:TRUE</li>
|
<li>CA:TRUE</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<h3>Create an intermediate key</h3>
|
<h2>Create an intermediate key</h2>
|
||||||
|
|
||||||
<pre><code>openssl ecparam -name secp384r1 -genkey | openssl ec -aes-256-cbc -out intermediate/private/intermediate.key.pem
|
<pre><code>openssl ecparam -name secp384r1 -genkey | openssl ec -aes-256-cbc -out intermediate/private/intermediate.key.pem
|
||||||
# Create strong intermediate key password
|
# Create strong intermediate key password
|
||||||
chmod 400 intermediate/private/intermediate.key.pem
|
chmod 400 intermediate/private/intermediate.key.pem
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<h3>Create an intermediate certificate signing request (CSR)</h3>
|
<h2>Create an intermediate certificate signing request (CSR)</h2>
|
||||||
|
|
||||||
<pre><code>openssl req -config openssl.cnf -new -key intermediate/private/intermediate.key.pem -out intermediate/csr/intermediate.csr.pem -subj '/C=US/ST=California/O=XXXX/OU=XXXX Certificate Authority/CN=XXXX Intermediate'
|
<pre><code>openssl req -config openssl.cnf -new -key intermediate/private/intermediate.key.pem -out intermediate/csr/intermediate.csr.pem -subj '/C=US/ST=California/O=XXXX/OU=XXXX Certificate Authority/CN=XXXX Intermediate'
|
||||||
# Enter intermediate key password
|
# Enter intermediate key password
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<h3>Sign intermediate cert with root key</h3>
|
<h2>Sign intermediate cert with root key</h2>
|
||||||
|
|
||||||
<pre><code>openssl ca -config openssl.cnf -name ca_root -extensions ext_intermediate -notext -in intermediate/csr/intermediate.csr.pem -out intermediate/certs/intermediate.cert.pem
|
<pre><code>openssl ca -config openssl.cnf -name ca_root -extensions ext_intermediate -notext -in intermediate/csr/intermediate.csr.pem -out intermediate/certs/intermediate.cert.pem
|
||||||
# Enter root key password
|
# Enter root key password
|
||||||
chmod 444 intermediate/certs/intermediate.cert.pem
|
chmod 444 intermediate/certs/intermediate.cert.pem
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<h3>Verify intermediate cert</h3>
|
<h2>Verify intermediate cert</h2>
|
||||||
|
|
||||||
<pre><code>openssl x509 -noout -text -in intermediate/certs/intermediate.cert.pem
|
<pre><code>openssl x509 -noout -text -in intermediate/certs/intermediate.cert.pem
|
||||||
openssl verify -CAfile root/certs/root.cert.pem intermediate/certs/intermediate.cert.pem
|
openssl verify -CAfile root/certs/root.cert.pem intermediate/certs/intermediate.cert.pem
|
||||||
@@ -197,13 +197,13 @@ openssl verify -CAfile root/certs/root.cert.pem intermediate/certs/intermediate.
|
|||||||
<li>OK</li>
|
<li>OK</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<h3>Create a chain certificate file</h3>
|
<h2>Create a chain certificate file</h2>
|
||||||
|
|
||||||
<pre><code>cat intermediate/certs/intermediate.cert.pem root/certs/root.cert.pem > intermediate/certs/chain.cert.pem
|
<pre><code>cat intermediate/certs/intermediate.cert.pem root/certs/root.cert.pem > intermediate/certs/chain.cert.pem
|
||||||
chmod 444 intermediate/certs/chain.cert.pem
|
chmod 444 intermediate/certs/chain.cert.pem
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<h3>Create a client key</h3>
|
<h2>Create a client key</h2>
|
||||||
|
|
||||||
<p>You can substitute “server” for “client” for a server cert.</p>
|
<p>You can substitute “server” for “client” for a server cert.</p>
|
||||||
|
|
||||||
@@ -212,19 +212,19 @@ chmod 444 intermediate/certs/chain.cert.pem
|
|||||||
chmod 400 client/private/test1.key.pem
|
chmod 400 client/private/test1.key.pem
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<h3>Create a client certificate signing request (CSR)</h3>
|
<h2>Create a client certificate signing request (CSR)</h2>
|
||||||
|
|
||||||
<pre><code>openssl req -config openssl.cnf -new -key client/private/test1.key.pem -out client/csr/test1.csr.pem -subj '/C=US/ST=California/O=XXXX/OU=XXXX Test/CN=XXXX Test 1'
|
<pre><code>openssl req -config openssl.cnf -new -key client/private/test1.key.pem -out client/csr/test1.csr.pem -subj '/C=US/ST=California/O=XXXX/OU=XXXX Test/CN=XXXX Test 1'
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<h3>Sign client cert with intermediate key</h3>
|
<h2>Sign client cert with intermediate key</h2>
|
||||||
|
|
||||||
<pre><code>openssl ca -config openssl.cnf -extensions ext_client -notext -in client/csr/test1.csr.pem -out client/certs/test1.cert.pem
|
<pre><code>openssl ca -config openssl.cnf -extensions ext_client -notext -in client/csr/test1.csr.pem -out client/certs/test1.cert.pem
|
||||||
# Enter intermediate key password
|
# Enter intermediate key password
|
||||||
chmod 444 client/certs/test1.cert.pem
|
chmod 444 client/certs/test1.cert.pem
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<h3>Verify client cert</h3>
|
<h2>Verify client cert</h2>
|
||||||
|
|
||||||
<pre><code>openssl x509 -noout -text -in client/certs/test1.cert.pem
|
<pre><code>openssl x509 -noout -text -in client/certs/test1.cert.pem
|
||||||
openssl verify -CAfile intermediate/certs/chain.cert.pem client/certs/test1.cert.pem
|
openssl verify -CAfile intermediate/certs/chain.cert.pem client/certs/test1.cert.pem
|
||||||
@@ -240,7 +240,7 @@ openssl verify -CAfile intermediate/certs/chain.cert.pem client/certs/test1.cert
|
|||||||
<li>OK</li>
|
<li>OK</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<h3>Create a PKCS#12 bundle for the client</h3>
|
<h2>Create a PKCS#12 bundle for the client</h2>
|
||||||
|
|
||||||
<p>This is an easy(er) way to get all the necessary keys & certs to the client in one package.</p>
|
<p>This is an easy(er) way to get all the necessary keys & certs to the client in one package.</p>
|
||||||
|
|
||||||
@@ -248,14 +248,14 @@ openssl verify -CAfile intermediate/certs/chain.cert.pem client/certs/test1.cert
|
|||||||
# Enter both the client key password, and a new password for the export; you'll need to give the latter to the client
|
# Enter both the client key password, and a new password for the export; you'll need to give the latter to the client
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<h3>Generate a certificate revocation list (CRL)</h3>
|
<h2>Generate a certificate revocation list (CRL)</h2>
|
||||||
|
|
||||||
<p>Initially empty. You can also do this for your root CA.</p>
|
<p>Initially empty. You can also do this for your root CA.</p>
|
||||||
|
|
||||||
<pre><code>openssl ca -config openssl.cnf -gencrl -out intermediate/crl/intermediate.crl.pem
|
<pre><code>openssl ca -config openssl.cnf -gencrl -out intermediate/crl/intermediate.crl.pem
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<h3>Verify certificate revocation list</h3>
|
<h2>Verify certificate revocation list</h2>
|
||||||
|
|
||||||
<pre><code>openssl crl -in intermediate/crl/intermediate.crl.pem -noout -text
|
<pre><code>openssl crl -in intermediate/crl/intermediate.crl.pem -noout -text
|
||||||
</code></pre>
|
</code></pre>
|
||||||
@@ -267,7 +267,7 @@ openssl verify -CAfile intermediate/certs/chain.cert.pem client/certs/test1.cert
|
|||||||
<li>Signature algorithm (ecdsa-with-SHA256)</li>
|
<li>Signature algorithm (ecdsa-with-SHA256)</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<h3>Revoke a certificate</h3>
|
<h2>Revoke a certificate</h2>
|
||||||
|
|
||||||
<p>Only do this if you need to. Find the certificate:</p>
|
<p>Only do this if you need to. Find the certificate:</p>
|
||||||
|
|
||||||
|
|||||||
@@ -13,16 +13,16 @@
|
|||||||
|
|
||||||
<p>Below are the steps to get the Nitrokey HSM to a working state where it can generate an EC key pair, and (self-)sign a cert with it. Hopefully many of these go away in the future, as support percolates into release versions and distribution packages.</p>
|
<p>Below are the steps to get the Nitrokey HSM to a working state where it can generate an EC key pair, and (self-)sign a cert with it. Hopefully many of these go away in the future, as support percolates into release versions and distribution packages.</p>
|
||||||
|
|
||||||
<h3>Hardware & setup</h3>
|
<h2>Hardware & setup</h2>
|
||||||
|
|
||||||
<p>These instructions were developed and tested on a Raspberry Pi. Base setup instructions are here. You’ll also need a Nitrokey HSM, obviously.</p>
|
<p>These instructions were developed and tested on a Raspberry Pi. Base setup instructions are here. You’ll also need a Nitrokey HSM, obviously.</p>
|
||||||
|
|
||||||
<h3>Install prerequisites</h3>
|
<h2>Install prerequisites</h2>
|
||||||
|
|
||||||
<pre><code>sudo apt-get install pcscd libpcsclite-dev libssl-dev libreadline-dev autoconf automake build-essential docbook-xsl xsltproc libtool pkg-config git
|
<pre><code>sudo apt-get install pcscd libpcsclite-dev libssl-dev libreadline-dev autoconf automake build-essential docbook-xsl xsltproc libtool pkg-config git
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<h3>libccid</h3>
|
<h2>libccid</h2>
|
||||||
|
|
||||||
<p>You’ll need a <a href="https://www.nitrokey.com/documentation/frequently-asked-questions#which-gnupg,-opensc-and-libccid-versions-are-required">newer version of libccid</a> than currently exists in Raspbian Jessie (1.4.22 > 1.4.18). You can download it for your platform here, or use the commands below for an RPi.</p>
|
<p>You’ll need a <a href="https://www.nitrokey.com/documentation/frequently-asked-questions#which-gnupg,-opensc-and-libccid-versions-are-required">newer version of libccid</a> than currently exists in Raspbian Jessie (1.4.22 > 1.4.18). You can download it for your platform here, or use the commands below for an RPi.</p>
|
||||||
|
|
||||||
@@ -30,7 +30,7 @@
|
|||||||
sudo dpkg -i libccid_1.4.22-1_armhf.deb
|
sudo dpkg -i libccid_1.4.22-1_armhf.deb
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<h3>Install libp11</h3>
|
<h2>Install libp11</h2>
|
||||||
|
|
||||||
<p>engine_pkcs11 requires >= 0.3.1. Raspbian Jessie has 0.2.8. Debian sid <a href="https://packages.debian.org/sid/libp11-2">has a package</a>, but you need the dev package as well, so you might as well build it.</p>
|
<p>engine_pkcs11 requires >= 0.3.1. Raspbian Jessie has 0.2.8. Debian sid <a href="https://packages.debian.org/sid/libp11-2">has a package</a>, but you need the dev package as well, so you might as well build it.</p>
|
||||||
|
|
||||||
@@ -43,7 +43,7 @@ sudo make install
|
|||||||
cd ..
|
cd ..
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<h3>Install engine_pkcs11</h3>
|
<h2>Install engine_pkcs11</h2>
|
||||||
|
|
||||||
<p>EC <a href="https://www.nitrokey.com/forum/viewtopic.php?t=1549">requires engine_pkcs11 >= 0.2.0</a>. Raspbian Jessie has 0.1.8. Debian <a href="https://packages.debian.org/sid/libengine-pkcs11-openssl">sid also has a package</a> that I haven’t tested.</p>
|
<p>EC <a href="https://www.nitrokey.com/forum/viewtopic.php?t=1549">requires engine_pkcs11 >= 0.2.0</a>. Raspbian Jessie has 0.1.8. Debian <a href="https://packages.debian.org/sid/libengine-pkcs11-openssl">sid also has a package</a> that I haven’t tested.</p>
|
||||||
|
|
||||||
@@ -56,7 +56,7 @@ sudo make install
|
|||||||
cd ..
|
cd ..
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<h3>Install OpenSC</h3>
|
<h2>Install OpenSC</h2>
|
||||||
|
|
||||||
<p>As of writing (2016/Mar/26), working support for the Nitrokey HSM <a href="https://www.nitrokey.com/documentation/frequently-asked-questions#which-gnupg,-opensc-and-libccid-versions-are-required">requires a build of OpenSC</a> that hasn’t made it into a package yet (0.16.0). They’ve also screwed up their repository branching, so master is behind the release branch and won’t work.</p>
|
<p>As of writing (2016/Mar/26), working support for the Nitrokey HSM <a href="https://www.nitrokey.com/documentation/frequently-asked-questions#which-gnupg,-opensc-and-libccid-versions-are-required">requires a build of OpenSC</a> that hasn’t made it into a package yet (0.16.0). They’ve also screwed up their repository branching, so master is behind the release branch and won’t work.</p>
|
||||||
|
|
||||||
@@ -69,24 +69,24 @@ sudo make install
|
|||||||
cd ..
|
cd ..
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<h3>Misc</h3>
|
<h2>Misc</h2>
|
||||||
|
|
||||||
<pre><code>sudo ldconfig
|
<pre><code>sudo ldconfig
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<h3>Initialize the device</h3>
|
<h2>Initialize the device</h2>
|
||||||
|
|
||||||
<pre><code>/usr/local/bin/sc-hsm-tool --initialize
|
<pre><code>/usr/local/bin/sc-hsm-tool --initialize
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<p>If this tells you that it can’t find the device, you probably forgot to update libccid, and need to start over. You’ll need to set an SO PIN and PIN the first time. The SO PIN should be 16 characters, and the PIN 6. Both should be all digits. They can technically be hex, but some apps get confused if they see letters.</p>
|
<p>If this tells you that it can’t find the device, you probably forgot to update libccid, and need to start over. You’ll need to set an SO PIN and PIN the first time. The SO PIN should be 16 characters, and the PIN 6. Both should be all digits. They can technically be hex, but some apps get confused if they see letters.</p>
|
||||||
|
|
||||||
<h3>Generate a test EC key pair</h3>
|
<h2>Generate a test EC key pair</h2>
|
||||||
|
|
||||||
<pre><code>/usr/local/bin/pkcs11-tool --module /usr/local/lib/opensc-pkcs11.so---login --keypairgen --key-type EC:prime256v1 --label test
|
<pre><code>/usr/local/bin/pkcs11-tool --module /usr/local/lib/opensc-pkcs11.so---login --keypairgen --key-type EC:prime256v1 --label test
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<h3>Generate a self-signed cert</h3>
|
<h2>Generate a self-signed cert</h2>
|
||||||
|
|
||||||
<pre><code>openssl
|
<pre><code>openssl
|
||||||
OpenSSL> engine -t -pre SO_PATH:/usr/lib/arm-linux-gnueabihf/openssl-1.0.0/engines/libpkcs11.so -pre ID:pkcs11 -pre LIST_ADD:1 -pre LOAD -pre MODULE_PATH:/usr/local/lib/pkcs11/opensc-pkcs11.so dynamic
|
OpenSSL> engine -t -pre SO_PATH:/usr/lib/arm-linux-gnueabihf/openssl-1.0.0/engines/libpkcs11.so -pre ID:pkcs11 -pre LIST_ADD:1 -pre LOAD -pre MODULE_PATH:/usr/local/lib/pkcs11/opensc-pkcs11.so dynamic
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
<p>XXXX is still our placeholder of choice.</p>
|
<p>XXXX is still our placeholder of choice.</p>
|
||||||
|
|
||||||
<h3>Create directory structure</h3>
|
<h2>Create directory structure</h2>
|
||||||
|
|
||||||
<pre><code>mkdir ca
|
<pre><code>mkdir ca
|
||||||
cd ca
|
cd ca
|
||||||
@@ -24,7 +24,7 @@ echo 1000 | tee {root,intermediate}/{serial,crlnumber}
|
|||||||
chmod 700 {client,server}/private
|
chmod 700 {client,server}/private
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<h3>Create openssl.cnf</h3>
|
<h2>Create openssl.cnf</h2>
|
||||||
|
|
||||||
<pre><code>cat > openssl.cnf <<'END'
|
<pre><code>cat > openssl.cnf <<'END'
|
||||||
openssl_conf = openssl_init
|
openssl_conf = openssl_init
|
||||||
@@ -142,12 +142,12 @@ init = 0
|
|||||||
END
|
END
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<h3>Tell future commands to use your new conf file</h3>
|
<h2>Tell future commands to use your new conf file</h2>
|
||||||
|
|
||||||
<pre><code>export OPENSSL_CONF=openssl.cnf
|
<pre><code>export OPENSSL_CONF=openssl.cnf
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<h3>Create a root key</h3>
|
<h2>Create a root key</h2>
|
||||||
|
|
||||||
<p>Insert your root HSM.</p>
|
<p>Insert your root HSM.</p>
|
||||||
|
|
||||||
@@ -155,14 +155,14 @@ END
|
|||||||
# Enter PIN
|
# Enter PIN
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<h3>Create a self-signed root cert</h3>
|
<h2>Create a self-signed root cert</h2>
|
||||||
|
|
||||||
<pre><code>openssl req -engine pkcs11 -keyform engine -key label_root -new -extensions ext_root -out root/certs/root.cert.pem -x509 -subj '/C=US/ST=California/O=XXXX/OU=XXXX Certificate Authority/CN=XXXX Root CA' -days 7300
|
<pre><code>openssl req -engine pkcs11 -keyform engine -key label_root -new -extensions ext_root -out root/certs/root.cert.pem -x509 -subj '/C=US/ST=California/O=XXXX/OU=XXXX Certificate Authority/CN=XXXX Root CA' -days 7300
|
||||||
# Enter PIN
|
# Enter PIN
|
||||||
chmod 444 root/certs/root.cert.pem
|
chmod 444 root/certs/root.cert.pem
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<h3>Verify root cert</h3>
|
<h2>Verify root cert</h2>
|
||||||
|
|
||||||
<pre><code>openssl x509 -noout -text -in root/certs/root.cert.pem
|
<pre><code>openssl x509 -noout -text -in root/certs/root.cert.pem
|
||||||
</code></pre>
|
</code></pre>
|
||||||
@@ -176,14 +176,14 @@ chmod 444 root/certs/root.cert.pem
|
|||||||
<li>CA:TRUE</li>
|
<li>CA:TRUE</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<h3>Import root cert onto HSM</h3>
|
<h2>Import root cert onto HSM</h2>
|
||||||
|
|
||||||
<pre><code>openssl x509 -in root/certs/root.cert.pem -out root/certs/root.cert.der -outform der
|
<pre><code>openssl x509 -in root/certs/root.cert.pem -out root/certs/root.cert.der -outform der
|
||||||
/usr/local/bin/pkcs11-tool --module /usr/local/lib/opensc-pkcs11.so --login --write-object root/certs/root.cert.der --type cert --label root
|
/usr/local/bin/pkcs11-tool --module /usr/local/lib/opensc-pkcs11.so --login --write-object root/certs/root.cert.der --type cert --label root
|
||||||
# Enter PIN
|
# Enter PIN
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<h3>Create an intermediate key</h3>
|
<h2>Create an intermediate key</h2>
|
||||||
|
|
||||||
<p>Insert your intermediate HSM</p>
|
<p>Insert your intermediate HSM</p>
|
||||||
|
|
||||||
@@ -191,13 +191,13 @@ chmod 444 root/certs/root.cert.pem
|
|||||||
# Enter PIN
|
# Enter PIN
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<h3>Create an intermediate certificate signing request (CSR)</h3>
|
<h2>Create an intermediate certificate signing request (CSR)</h2>
|
||||||
|
|
||||||
<pre><code>openssl req -engine pkcs11 -keyform engine -new -key label_intermediate -out intermediate/csr/intermediate.csr.pem -subj '/C=US/ST=California/O=XXXX/OU=XXXX Certificate Authority/CN=XXXX Intermediate'
|
<pre><code>openssl req -engine pkcs11 -keyform engine -new -key label_intermediate -out intermediate/csr/intermediate.csr.pem -subj '/C=US/ST=California/O=XXXX/OU=XXXX Certificate Authority/CN=XXXX Intermediate'
|
||||||
# Enter PIN
|
# Enter PIN
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<h3>Sign intermediate cert with root key</h3>
|
<h2>Sign intermediate cert with root key</h2>
|
||||||
|
|
||||||
<p>Insert your root HSM</p>
|
<p>Insert your root HSM</p>
|
||||||
|
|
||||||
@@ -206,7 +206,7 @@ chmod 444 root/certs/root.cert.pem
|
|||||||
chmod 444 intermediate/certs/intermediate.cert.pem
|
chmod 444 intermediate/certs/intermediate.cert.pem
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<h3>Verify intermediate cert</h3>
|
<h2>Verify intermediate cert</h2>
|
||||||
|
|
||||||
<pre><code>openssl x509 -noout -text -in intermediate/certs/intermediate.cert.pem
|
<pre><code>openssl x509 -noout -text -in intermediate/certs/intermediate.cert.pem
|
||||||
openssl verify -CAfile root/certs/root.cert.pem intermediate/certs/intermediate.cert.pem
|
openssl verify -CAfile root/certs/root.cert.pem intermediate/certs/intermediate.cert.pem
|
||||||
@@ -222,7 +222,7 @@ openssl verify -CAfile root/certs/root.cert.pem intermediate/certs/intermediate.
|
|||||||
<li>OK</li>
|
<li>OK</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<h3>Import root & intermediate certs onto HSM</h3>
|
<h2>Import root & intermediate certs onto HSM</h2>
|
||||||
|
|
||||||
<p>Insert your intermediate HSM</p>
|
<p>Insert your intermediate HSM</p>
|
||||||
|
|
||||||
@@ -233,19 +233,19 @@ openssl verify -CAfile root/certs/root.cert.pem intermediate/certs/intermediate.
|
|||||||
# Enter PIN
|
# Enter PIN
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<h3>Create a chain certificate file</h3>
|
<h2>Create a chain certificate file</h2>
|
||||||
|
|
||||||
<pre><code>cat intermediate/certs/intermediate.cert.pem root/certs/root.cert.pem > intermediate/certs/chain.cert.pem
|
<pre><code>cat intermediate/certs/intermediate.cert.pem root/certs/root.cert.pem > intermediate/certs/chain.cert.pem
|
||||||
chmod 444 intermediate/certs/chain.cert.pem
|
chmod 444 intermediate/certs/chain.cert.pem
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<h3>CA setup done!</h3>
|
<h2>CA setup done!</h2>
|
||||||
|
|
||||||
<p>Take your root HSM, if you have a separate one, and lock it in a safe somewhere; you won’t need it for regular use.</p>
|
<p>Take your root HSM, if you have a separate one, and lock it in a safe somewhere; you won’t need it for regular use.</p>
|
||||||
|
|
||||||
<p>The following steps are examples of how to use your new CA.</p>
|
<p>The following steps are examples of how to use your new CA.</p>
|
||||||
|
|
||||||
<h3>Create a client key</h3>
|
<h2>Create a client key</h2>
|
||||||
|
|
||||||
<p>You can substitute “server” for “client” for a server cert.</p>
|
<p>You can substitute “server” for “client” for a server cert.</p>
|
||||||
|
|
||||||
@@ -254,19 +254,19 @@ chmod 444 intermediate/certs/chain.cert.pem
|
|||||||
chmod 400 client/private/test1.key.pem
|
chmod 400 client/private/test1.key.pem
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<h3>Create a client certificate signing request (CSR)</h3>
|
<h2>Create a client certificate signing request (CSR)</h2>
|
||||||
|
|
||||||
<pre><code>openssl req -new -key client/private/test1.key.pem -out client/csr/test1.csr.pem -subj '/C=US/ST=California/O=XXXX/OU=XXXX Test/CN=XXXX Test 1'
|
<pre><code>openssl req -new -key client/private/test1.key.pem -out client/csr/test1.csr.pem -subj '/C=US/ST=California/O=XXXX/OU=XXXX Test/CN=XXXX Test 1'
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<h3>Sign client cert with intermediate key</h3>
|
<h2>Sign client cert with intermediate key</h2>
|
||||||
|
|
||||||
<pre><code>openssl ca -engine pkcs11 -keyform engine -extensions ext_client -notext -in client/csr/test1.csr.pem -out client/certs/test1.cert.pem
|
<pre><code>openssl ca -engine pkcs11 -keyform engine -extensions ext_client -notext -in client/csr/test1.csr.pem -out client/certs/test1.cert.pem
|
||||||
# Enter PIN
|
# Enter PIN
|
||||||
chmod 444 client/certs/test1.cert.pem
|
chmod 444 client/certs/test1.cert.pem
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<h3>Verify client cert</h3>
|
<h2>Verify client cert</h2>
|
||||||
|
|
||||||
<pre><code>openssl x509 -noout -text -in client/certs/test1.cert.pem
|
<pre><code>openssl x509 -noout -text -in client/certs/test1.cert.pem
|
||||||
openssl verify -CAfile intermediate/certs/chain.cert.pem client/certs/test1.cert.pem
|
openssl verify -CAfile intermediate/certs/chain.cert.pem client/certs/test1.cert.pem
|
||||||
@@ -282,7 +282,7 @@ openssl verify -CAfile intermediate/certs/chain.cert.pem client/certs/test1.cert
|
|||||||
<li>OK</li>
|
<li>OK</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<h3>Create a PKCS#12 bundle for the client</h3>
|
<h2>Create a PKCS#12 bundle for the client</h2>
|
||||||
|
|
||||||
<p>This is an easy(er) way to get all the necessary keys & certs to the client in one package.</p>
|
<p>This is an easy(er) way to get all the necessary keys & certs to the client in one package.</p>
|
||||||
|
|
||||||
@@ -290,14 +290,14 @@ openssl verify -CAfile intermediate/certs/chain.cert.pem client/certs/test1.cert
|
|||||||
# Enter both the client key password, and a new password for the export; you'll need to give the latter to the client
|
# Enter both the client key password, and a new password for the export; you'll need to give the latter to the client
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<h3>Generate a certificate revocation list (CRL)</h3>
|
<h2>Generate a certificate revocation list (CRL)</h2>
|
||||||
|
|
||||||
<p>Initially empty. You can also do this for your root CA (with its HSM inserted).</p>
|
<p>Initially empty. You can also do this for your root CA (with its HSM inserted).</p>
|
||||||
|
|
||||||
<pre><code>openssl ca -engine pkcs11 -keyform engine -gencrl -out intermediate/crl/intermediate.crl.pem
|
<pre><code>openssl ca -engine pkcs11 -keyform engine -gencrl -out intermediate/crl/intermediate.crl.pem
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<h3>Verify certificate revocation list</h3>
|
<h2>Verify certificate revocation list</h2>
|
||||||
|
|
||||||
<pre><code>openssl crl -in intermediate/crl/intermediate.crl.pem -noout -text
|
<pre><code>openssl crl -in intermediate/crl/intermediate.crl.pem -noout -text
|
||||||
</code></pre>
|
</code></pre>
|
||||||
@@ -309,7 +309,7 @@ openssl verify -CAfile intermediate/certs/chain.cert.pem client/certs/test1.cert
|
|||||||
<li>Signature algorithm (ecdsa-with-SHA256)</li>
|
<li>Signature algorithm (ecdsa-with-SHA256)</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<h3>Revoke a certificate</h3>
|
<h2>Revoke a certificate</h2>
|
||||||
|
|
||||||
<p>Only do this if you need to. Find the certificate:</p>
|
<p>Only do this if you need to. Find the certificate:</p>
|
||||||
|
|
||||||
|
|||||||
@@ -5,18 +5,18 @@
|
|||||||
|
|
||||||
<p>If you’re building system images, you’re going to do a lot of debootstrap, which is going to fetch a lot of packages. On a fast system, that’ll be the slowest part of the process. Here’s how to cache.</p>
|
<p>If you’re building system images, you’re going to do a lot of debootstrap, which is going to fetch a lot of packages. On a fast system, that’ll be the slowest part of the process. Here’s how to cache.</p>
|
||||||
|
|
||||||
<h3>Install apt-cacher-ng</h3>
|
<h2>Install apt-cacher-ng</h2>
|
||||||
|
|
||||||
<pre><code>sudo apt-get install squid-deb-proxy
|
<pre><code>sudo apt-get install squid-deb-proxy
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<h3>Tell programs to use the proxy</h3>
|
<h2>Tell programs to use the proxy</h2>
|
||||||
|
|
||||||
<pre><code>export http_proxy=http://127.0.0.1:8000
|
<pre><code>export http_proxy=http://127.0.0.1:8000
|
||||||
# Note that you'll need to re-export this before any use of debootstrap
|
# Note that you'll need to re-export this before any use of debootstrap
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<h3>Tell sudo to pass through http_proxy</h3>
|
<h2>Tell sudo to pass through http_proxy</h2>
|
||||||
|
|
||||||
<pre><code>sudo visudo
|
<pre><code>sudo visudo
|
||||||
# Add the line after the env_reset line:
|
# Add the line after the env_reset line:
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
<li>Not assume that the WLAN MAC address is the only MAC at the other end of the link. This assumption is frequently used to reduce the effect of broadcast traffic in a WiFi environment by filtering. There may be settings like “Multicast optimization”, “Broadcast optimization”, or “DHCP optimization” that you need to turn off.</li>
|
<li>Not assume that the WLAN MAC address is the only MAC at the other end of the link. This assumption is frequently used to reduce the effect of broadcast traffic in a WiFi environment by filtering. There may be settings like “Multicast optimization”, “Broadcast optimization”, or “DHCP optimization” that you need to turn off.</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<h3>Bridging</h3>
|
<h2>Bridging</h2>
|
||||||
|
|
||||||
<p>Linux supports bridging. There’s a bridge-utils package in Ubuntu with the tools you need:</p>
|
<p>Linux supports bridging. There’s a bridge-utils package in Ubuntu with the tools you need:</p>
|
||||||
|
|
||||||
@@ -35,7 +35,7 @@ can't add wlan0 to bridge br0: Operation not supported
|
|||||||
|
|
||||||
<p>Googling this error produces a wide range of well-meaning yet completely unhelpful results.</p>
|
<p>Googling this error produces a wide range of well-meaning yet completely unhelpful results.</p>
|
||||||
|
|
||||||
<h3>Enable 4 address mode</h3>
|
<h2>Enable 4 address mode</h2>
|
||||||
|
|
||||||
<p>To be able to add a WiFi interface to a bridge, you have to put it into 4-address mode first:</p>
|
<p>To be able to add a WiFi interface to a bridge, you have to put it into 4-address mode first:</p>
|
||||||
|
|
||||||
@@ -53,7 +53,7 @@ sudo iw dev wlan0 set 4addr on
|
|||||||
|
|
||||||
<p>You should now be able to fetch an IP on br0 via DHCP. Unless, of course, you need wpa_supplicant to work…</p>
|
<p>You should now be able to fetch an IP on br0 via DHCP. Unless, of course, you need wpa_supplicant to work…</p>
|
||||||
|
|
||||||
<h3>wpa_supplicant</h3>
|
<h2>wpa_supplicant</h2>
|
||||||
|
|
||||||
<p>wpa_supplicant needs to be bridge-aware to work with 4-address mode. Fortunately, it has a flag (-b) to set the bridge interface. Unfortunately, this flag is broken in 2.1, the version in Ubuntu Trusty. I verified that it works in wpa_supplicant 2.5 built from source; I haven’t verified 2.4 from Xenial.</p>
|
<p>wpa_supplicant needs to be bridge-aware to work with 4-address mode. Fortunately, it has a flag (-b) to set the bridge interface. Unfortunately, this flag is broken in 2.1, the version in Ubuntu Trusty. I verified that it works in wpa_supplicant 2.5 built from source; I haven’t verified 2.4 from Xenial.</p>
|
||||||
|
|
||||||
@@ -64,7 +64,7 @@ sudo iw dev wlan0 set 4addr on
|
|||||||
|
|
||||||
<p>With that working, the interface should get to wpa_state=COMPLETED, and br0 should work normally. Remember that wlan0 will still be unusable directly.</p>
|
<p>With that working, the interface should get to wpa_state=COMPLETED, and br0 should work normally. Remember that wlan0 will still be unusable directly.</p>
|
||||||
|
|
||||||
<h3>Ordering</h3>
|
<h2>Ordering</h2>
|
||||||
|
|
||||||
<p>Bringing up these interfaces is tricky; the ordering is annoying.</p>
|
<p>Bringing up these interfaces is tricky; the ordering is annoying.</p>
|
||||||
|
|
||||||
@@ -74,7 +74,7 @@ sudo iw dev wlan0 set 4addr on
|
|||||||
<li>wpa_supplicant must be running before you can get an IP address on br0</li>
|
<li>wpa_supplicant must be running before you can get an IP address on br0</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<h3>Putting it together</h3>
|
<h2>Putting it together</h2>
|
||||||
|
|
||||||
<p>Because of the ordering issues, it’s easier to treat this all as one interface that has to come up together. Here’s an example interface stanza that does this:</p>
|
<p>Because of the ordering issues, it’s easier to treat this all as one interface that has to come up together. Here’s an example interface stanza that does this:</p>
|
||||||
|
|
||||||
|
|||||||
@@ -6,9 +6,7 @@
|
|||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<footer>
|
<footer>🔥🐄</footer>
|
||||||
<h1>*</h1>
|
|
||||||
</footer>
|
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -34,42 +34,34 @@ img {
|
|||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
header {
|
header, footer {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin-bottom: 20px;
|
margin-top: 10px;
|
||||||
}
|
margin-bottom: 15px;
|
||||||
|
|
||||||
footer {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1, h2, h3, h4 {
|
|
||||||
font-size: 17px;
|
font-size: 17px;
|
||||||
}
|
font-weight: bold;
|
||||||
|
|
||||||
h1 {
|
|
||||||
color: red;
|
color: red;
|
||||||
}
|
}
|
||||||
|
|
||||||
h1 a {
|
footer {
|
||||||
|
filter: grayscale(1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
header a {
|
||||||
color: red;
|
color: red;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
h2 {
|
h1, h2 {
|
||||||
|
font-size: 17px;
|
||||||
|
margin-top: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
margin-top: 0.5em;
|
margin-top: 7px;
|
||||||
margin-bottom: 0.5em;
|
margin-bottom: 7px;
|
||||||
}
|
|
||||||
|
|
||||||
h3 {
|
|
||||||
font-weight: bold;
|
|
||||||
margin-top: 2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
h4 {
|
|
||||||
font-weight: normal;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
article {
|
article {
|
||||||
@@ -126,7 +118,7 @@ code {
|
|||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
}
|
}
|
||||||
|
|
||||||
h1, h2, h3, h4 {
|
h1, h2 {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,8 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta name=viewport content="width=device-width, initial-scale=1.0">
|
<meta name=viewport content="width=device-width, initial-scale=1.0">
|
||||||
<meta name=theme-color content=#000000>
|
<meta name=theme-color content=#000000>
|
||||||
<meta name=description content="Ian "flamingcow" Gulliver's external memory of technical how-to articles and other musings">
|
<meta name=description content="flamingcow's external memory of technical how-to articles and other musings">
|
||||||
|
<meta name=author content="Ian "flamingcow" Gulliver">
|
||||||
<link rel=icon href="data:image/png;base64,<!--# include file="icon-cow.png.base64" -->">
|
<link rel=icon href="data:image/png;base64,<!--# include file="icon-cow.png.base64" -->">
|
||||||
<style>
|
<style>
|
||||||
<!--# include file="style.css" -->
|
<!--# include file="style.css" -->
|
||||||
@@ -12,36 +13,24 @@
|
|||||||
<title><!--# echo var="title" default="where the flamingcow roams" --></title>
|
<title><!--# echo var="title" default="where the flamingcow roams" --></title>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class=<!--# echo var="class" -->>
|
<body class="<!--# echo var="class" default="" -->">
|
||||||
|
|
||||||
<header>
|
<header>
|
||||||
<h1><a href=.>where the flamingcow roams</a></h1>
|
<a href=.>where the flamingcow roams</a>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<main>
|
<main>
|
||||||
|
|
||||||
<!--# if expr="$title" -->
|
<!--# if expr="$title" -->
|
||||||
<script type="application/ld+json">
|
|
||||||
{
|
|
||||||
"@context": "https://schema.org",
|
|
||||||
"@type": "BlogPosting",
|
|
||||||
"author": "Ian \"flamingcow\" Gulliver",
|
|
||||||
"headline": "<!--# echo var="title" -->",
|
|
||||||
"datePublished": "<!--# echo var="date" -->"
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<article>
|
<article>
|
||||||
<!--# endif -->
|
<!--# endif -->
|
||||||
|
|
||||||
<!--# if expr="$date" -->
|
<!--# if expr="$date" -->
|
||||||
<aside>
|
<time><!--# echo var="date" --></time>
|
||||||
<h4><!--# echo var="date" --></h4>
|
|
||||||
</aside>
|
|
||||||
<!--# endif -->
|
<!--# endif -->
|
||||||
|
|
||||||
<!--# if expr="$title" -->
|
<!--# if expr="$title" -->
|
||||||
<h2><!--# echo var="title" --></h2>
|
<h1><!--# echo var="title" --></h1>
|
||||||
<!--# endif -->
|
<!--# endif -->
|
||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
<!--# include file="include/top.html" -->
|
<!--# include file="include/top.html" -->
|
||||||
|
|
||||||
### The Players
|
## The Players
|
||||||
|
|
||||||
I’ll be referring to 3 hosts:
|
I’ll be referring to 3 hosts:
|
||||||
|
|
||||||
@@ -11,7 +11,7 @@ I’ll be referring to 3 hosts:
|
|||||||
* B: The bounce host; this machine is unfirewalled.
|
* B: The bounce host; this machine is unfirewalled.
|
||||||
* C: The client.
|
* C: The client.
|
||||||
|
|
||||||
### Configuring B
|
## Configuring B
|
||||||
|
|
||||||
Some sshd configuration needs to be done on B before any of this will work. In the sshd\_config file (/etc/ssh/sshd\_config on Debian):
|
Some sshd configuration needs to be done on B before any of this will work. In the sshd\_config file (/etc/ssh/sshd\_config on Debian):
|
||||||
|
|
||||||
@@ -20,7 +20,7 @@ Some sshd configuration needs to be done on B before any of this will work. In t
|
|||||||
|
|
||||||
Remember to restart sshd after making changes (/etc/init.d/ssh restart).
|
Remember to restart sshd after making changes (/etc/init.d/ssh restart).
|
||||||
|
|
||||||
### Building the Tunnel
|
## Building the Tunnel
|
||||||
|
|
||||||
On A, run:
|
On A, run:
|
||||||
|
|
||||||
@@ -34,7 +34,7 @@ You should now be able to connect to the port on B and be talking to A. To get t
|
|||||||
|
|
||||||
As with all shell commands, put a “&” on the end to run it in the background.
|
As with all shell commands, put a “&” on the end to run it in the background.
|
||||||
|
|
||||||
### Tunnelling FTP
|
## Tunnelling FTP
|
||||||
|
|
||||||
Due to a trick in the FTP protocol, you can use this tunnelling arrangement but have FTP data connections go directly from A to C, without touching B. This only works with so-called “active” FTP (using the PORT command instead of PASV). C must also be unfirewalled for this to work.
|
Due to a trick in the FTP protocol, you can use this tunnelling arrangement but have FTP data connections go directly from A to C, without touching B. This only works with so-called “active” FTP (using the PORT command instead of PASV). C must also be unfirewalled for this to work.
|
||||||
|
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ On A:
|
|||||||
|
|
||||||
SHOW DATABASES;
|
SHOW DATABASES;
|
||||||
|
|
||||||
### The AUTO\_INCREMENT problem
|
## The AUTO\_INCREMENT problem
|
||||||
|
|
||||||
AUTO\_INCREMENT-type columns get used in just about every MySQL table. They’re a quick way to build primary keys without thinking. However, there are obvious problems in a multi-master setup (if inserts happen on both servers at the same time, they’ll both get the same ID). The official MySQL solution (start the IDs on both servers at numbers significantly different from each other) is a nasty hack.
|
AUTO\_INCREMENT-type columns get used in just about every MySQL table. They’re a quick way to build primary keys without thinking. However, there are obvious problems in a multi-master setup (if inserts happen on both servers at the same time, they’ll both get the same ID). The official MySQL solution (start the IDs on both servers at numbers significantly different from each other) is a nasty hack.
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ I’ve been doing alot of work on methods for using multiple network interfaces
|
|||||||
1. Do you want your interfaces to share bandwidth when both are up?<br>
|
1. Do you want your interfaces to share bandwidth when both are up?<br>
|
||||||
Yes? __bonding:balance-alb__. No? __bonding:active-backup__.
|
Yes? __bonding:balance-alb__. No? __bonding:active-backup__.
|
||||||
|
|
||||||
### STP
|
## STP
|
||||||
|
|
||||||
This bonding method actually uses Linux’s support for interface bridging. If a bridge is set up between two interfaces connected to the same network and spanning tree protocol is activated, one interface will be put into blocking state and won’t pass traffic. This doesn’t aggregate bandwidth between interfaces when both are up, but it has the interesting effect of allowing the server to bridge traffic between the switches if there are no other available connections. Special configuration at the switches is required to prevent it from being used as a link under normal circumstances.
|
This bonding method actually uses Linux’s support for interface bridging. If a bridge is set up between two interfaces connected to the same network and spanning tree protocol is activated, one interface will be put into blocking state and won’t pass traffic. This doesn’t aggregate bandwidth between interfaces when both are up, but it has the interesting effect of allowing the server to bridge traffic between the switches if there are no other available connections. Special configuration at the switches is required to prevent it from being used as a link under normal circumstances.
|
||||||
|
|
||||||
@@ -57,7 +57,7 @@ And on the IOS switches:
|
|||||||
|
|
||||||
One side of one interface should be blocking.
|
One side of one interface should be blocking.
|
||||||
|
|
||||||
### bonding
|
## bonding
|
||||||
|
|
||||||
For any of the bonding methods, you’ll need the ifenslave program. In Debian:
|
For any of the bonding methods, you’ll need the ifenslave program. In Debian:
|
||||||
|
|
||||||
@@ -78,7 +78,7 @@ Then run:
|
|||||||
|
|
||||||
ifup bond0
|
ifup bond0
|
||||||
|
|
||||||
### bonding:active-backup
|
## bonding:active-backup
|
||||||
|
|
||||||
This bonding mode keeps one interface completely blocked (including not sending ARP replies out it), using it strictly as a backup.
|
This bonding mode keeps one interface completely blocked (including not sending ARP replies out it), using it strictly as a backup.
|
||||||
|
|
||||||
@@ -88,7 +88,7 @@ First:
|
|||||||
|
|
||||||
Follow the general bonding instructions above, and you’re all set!
|
Follow the general bonding instructions above, and you’re all set!
|
||||||
|
|
||||||
### bonding:802.3ad
|
## bonding:802.3ad
|
||||||
|
|
||||||
This bonding mode uses the standardized IEEE 802.3ad bonding method, with a protocol (LACP) for both sides to agree on bonding information. All links must be the same speed and duplex. The balancing method between links is determined by each end; a single connection will only go over one link, and sometimes traffic with a single (ethernet-level) peer will use a single link as well.
|
This bonding mode uses the standardized IEEE 802.3ad bonding method, with a protocol (LACP) for both sides to agree on bonding information. All links must be the same speed and duplex. The balancing method between links is determined by each end; a single connection will only go over one link, and sometimes traffic with a single (ethernet-level) peer will use a single link as well.
|
||||||
|
|
||||||
@@ -110,7 +110,7 @@ After you’ve done this for all the interfaces:
|
|||||||
|
|
||||||
Then follow the general bonding instructions.
|
Then follow the general bonding instructions.
|
||||||
|
|
||||||
### bonding:balance-alb
|
## bonding:balance-alb
|
||||||
|
|
||||||
This bonding mode balances outgoing traffic accoridng to interface speed and usage. It intercepts and rewrites outgoing ARP replies to make them come from different physical interfaces, tricking the network fabric into balancing incoming traffic as well.
|
This bonding mode balances outgoing traffic accoridng to interface speed and usage. It intercepts and rewrites outgoing ARP replies to make them come from different physical interfaces, tricking the network fabric into balancing incoming traffic as well.
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
This post is going to stray a bit from my usual geeky fare. I’m being asking far too much to help sort out haphazard home network designs that are causing real problems for their users. I decided to collect all the answers that I’ve given together in a single place that I can point to when asked.
|
This post is going to stray a bit from my usual geeky fare. I’m being asking far too much to help sort out haphazard home network designs that are causing real problems for their users. I decided to collect all the answers that I’ve given together in a single place that I can point to when asked.
|
||||||
|
|
||||||
### General Principles
|
## General Principles
|
||||||
|
|
||||||
Simplicity
|
Simplicity
|
||||||
|
|
||||||
@@ -15,7 +15,7 @@ You get what you pay for
|
|||||||
|
|
||||||
> A Cisco Aironet is going to crash less than a Linksys access point. A Cisco switch is going to provide better throughput than a NetGear one. This isn’t a hard-and-fast rule; there are certainly decent, cheap network devices out there. However, generally, if a device has a plastic case and an external power supply and you’ve got more than 3 people depending on it, you’re going to regret the decision.
|
> A Cisco Aironet is going to crash less than a Linksys access point. A Cisco switch is going to provide better throughput than a NetGear one. This isn’t a hard-and-fast rule; there are certainly decent, cheap network devices out there. However, generally, if a device has a plastic case and an external power supply and you’ve got more than 3 people depending on it, you’re going to regret the decision.
|
||||||
|
|
||||||
### Sorting out the devices
|
## Sorting out the devices
|
||||||
|
|
||||||
1. Diagram your network. Knowing what you have and how it’s all connected together is a critical first step toward fixing any of it. A complete diagram looks like:<br>
|
1. Diagram your network. Knowing what you have and how it’s all connected together is a critical first step toward fixing any of it. A complete diagram looks like:<br>
|
||||||
<img src="data:image/webp;base64,<!--# include file="images/sample-network.webp.base64" -->" alt=""><br>
|
<img src="data:image/webp;base64,<!--# include file="images/sample-network.webp.base64" -->" alt=""><br>
|
||||||
@@ -32,7 +32,7 @@ You get what you pay for
|
|||||||
|
|
||||||
You should see one or more lines starting with DHCPOFFER and telling you where the offer came from. If you see more than one source of offers, you need to eliminate extra DHCP servers.
|
You should see one or more lines starting with DHCPOFFER and telling you where the offer came from. If you see more than one source of offers, you need to eliminate extra DHCP servers.
|
||||||
|
|
||||||
### Troubleshooting slowness
|
## Troubleshooting slowness
|
||||||
|
|
||||||
By far the most common network issue seems to be nebulous “slowness”. We’ll try to eliminate possibilities one by one.
|
By far the most common network issue seems to be nebulous “slowness”. We’ll try to eliminate possibilities one by one.
|
||||||
|
|
||||||
@@ -60,11 +60,11 @@ By far the most common network issue seems to be nebulous “slowness”. We’l
|
|||||||
|
|
||||||
You’ll want to make the window a bit bigger. This application gives you real time timing data following the route from your network to firestuff.org. Watch the average times and loss percentages. Nothing above 0% is really acceptable loss; your ISP will probably claim that it is, but they’re lying. Remember that the numbers are cumulative; if hop 3 is dropping packets, those drops will effect hop 3 and everything beyond it. However, it’s really hop 3’s problem, and if hop 6 has a problem, it’ll be hard to see until you get the closer issue cleared up.
|
You’ll want to make the window a bit bigger. This application gives you real time timing data following the route from your network to firestuff.org. Watch the average times and loss percentages. Nothing above 0% is really acceptable loss; your ISP will probably claim that it is, but they’re lying. Remember that the numbers are cumulative; if hop 3 is dropping packets, those drops will effect hop 3 and everything beyond it. However, it’s really hop 3’s problem, and if hop 6 has a problem, it’ll be hard to see until you get the closer issue cleared up.
|
||||||
|
|
||||||
### Troubleshooting idle disconnects
|
## Troubleshooting idle disconnects
|
||||||
|
|
||||||
Do you have long-running connections (SSH, telnet, MySQL, etc.) that get disconnected when they’re not doing anything? It’s your NAT device’s fault. Period. If it doesn’t have a setting to change the maximum idle time for a connection, throw it out and buy one that does.
|
Do you have long-running connections (SSH, telnet, MySQL, etc.) that get disconnected when they’re not doing anything? It’s your NAT device’s fault. Period. If it doesn’t have a setting to change the maximum idle time for a connection, throw it out and buy one that does.
|
||||||
|
|
||||||
### Troubleshooting wireless problems
|
## Troubleshooting wireless problems
|
||||||
|
|
||||||
1. Does rebooting your wireless router/access point fix it? Throw it out and buy a real one (I kept buying new Linksys/NetGear products until I gave up and started buying Cisco. Oddly, since then, things work).
|
1. Does rebooting your wireless router/access point fix it? Throw it out and buy a real one (I kept buying new Linksys/NetGear products until I gave up and started buying Cisco. Oddly, since then, things work).
|
||||||
1. Are you in an area with a lot of access points? Time to switch to 802.11a; the hardware’s more expensive and less often included by default in laptops, but there are many more distinct channels (802.11b/g only has 3) and fewer other users.
|
1. Are you in an area with a lot of access points? Time to switch to 802.11a; the hardware’s more expensive and less often included by default in laptops, but there are many more distinct channels (802.11b/g only has 3) and fewer other users.
|
||||||
|
|||||||
@@ -5,39 +5,39 @@
|
|||||||
|
|
||||||
After getting the Internet connection all tuned up, it's time to talk network speed.
|
After getting the Internet connection all tuned up, it's time to talk network speed.
|
||||||
|
|
||||||
### How fast do you need to go?
|
## How fast do you need to go?
|
||||||
|
|
||||||
Talking about gigabit speeds around the office drew some incredulity. Most users seem to be used to talking about Internet connection speeds in the sub-10mbit range, so a 10mbit hub (which my new apartment came prewired with) and 802.11b (6mbit/s TCP) or at least 802.11g (~30mbit/s TCP) will pretty much suffice. Political arguments about the mess that is US last-mile Internet connections aside, however, there are expensive options at higher speeds. Some areas have FiOS (though Verizon has apparently stopped rolling it out), and Comcast has a 50mbit/s "Extreme" plan in my area for $115/month. DOCSIS 3 supports up to ~160mbit/s link speed. Broadband speeds don't obey Moore's law (mostly due to the enormous infrastructure investment required to deploy new tech), but we'll still probably see cable plans breaking the 100mbit/s barrier in 3 or 4 years max. In short, it's a gigabit ethernet (~700mbit/s in real life) and 802.11n (~150mbit/s with today's gear) world for the short- to medium-term.
|
Talking about gigabit speeds around the office drew some incredulity. Most users seem to be used to talking about Internet connection speeds in the sub-10mbit range, so a 10mbit hub (which my new apartment came prewired with) and 802.11b (6mbit/s TCP) or at least 802.11g (~30mbit/s TCP) will pretty much suffice. Political arguments about the mess that is US last-mile Internet connections aside, however, there are expensive options at higher speeds. Some areas have FiOS (though Verizon has apparently stopped rolling it out), and Comcast has a 50mbit/s "Extreme" plan in my area for $115/month. DOCSIS 3 supports up to ~160mbit/s link speed. Broadband speeds don't obey Moore's law (mostly due to the enormous infrastructure investment required to deploy new tech), but we'll still probably see cable plans breaking the 100mbit/s barrier in 3 or 4 years max. In short, it's a gigabit ethernet (~700mbit/s in real life) and 802.11n (~150mbit/s with today's gear) world for the short- to medium-term.
|
||||||
|
|
||||||
### Defining your users
|
## Defining your users
|
||||||
|
|
||||||
My use cases for wireless at home divide pretty neatly into two categories: high-bandwidth, low-latency streaming to fixed points (Mac Minis hooked up to my TVs), and bursty-bandwidth, can-survive-momentary-latency clients that move around a lot (laptop, cellphone, iPad). I'd like both to be able to max out my Internet connection, but the video streaming needs to be able to do better inside my network (streaming from my iMac). This may get murkier once Apple get iTunes streaming to the iPad working.
|
My use cases for wireless at home divide pretty neatly into two categories: high-bandwidth, low-latency streaming to fixed points (Mac Minis hooked up to my TVs), and bursty-bandwidth, can-survive-momentary-latency clients that move around a lot (laptop, cellphone, iPad). I'd like both to be able to max out my Internet connection, but the video streaming needs to be able to do better inside my network (streaming from my iMac). This may get murkier once Apple get iTunes streaming to the iPad working.
|
||||||
|
|
||||||
### The first hop
|
## The first hop
|
||||||
|
|
||||||
No amount of optimization on the wireless side is going to help if the cable modem to router hop can't push the full speed of the 'net connection (this presumes that they're two different devices for you). First, both should support GigE (I have a Motorola SB6120 and a D-Link DIR-855). It's harder than it should be to verify the connection speed between these two; in the end, I had to force the link on the router end to 1000mbit/s-only, then make sure it still connected.
|
No amount of optimization on the wireless side is going to help if the cable modem to router hop can't push the full speed of the 'net connection (this presumes that they're two different devices for you). First, both should support GigE (I have a Motorola SB6120 and a D-Link DIR-855). It's harder than it should be to verify the connection speed between these two; in the end, I had to force the link on the router end to 1000mbit/s-only, then make sure it still connected.
|
||||||
|
|
||||||
My apartment isn't wired ideally, so the cable modem and router are in different places. The apartment has ethernet throughout, but it's only wired with 2 pairs (out of the 4 pairs in an RJ45 connector); that's only sufficient for 100mbit/s links. Kacirek brought over the toolkit and we appropriated some telephone wiring to serve as the extra two pairs, replacing the 10mbit hub with an ethernet coupler.
|
My apartment isn't wired ideally, so the cable modem and router are in different places. The apartment has ethernet throughout, but it's only wired with 2 pairs (out of the 4 pairs in an RJ45 connector); that's only sufficient for 100mbit/s links. Kacirek brought over the toolkit and we appropriated some telephone wiring to serve as the extra two pairs, replacing the 10mbit hub with an ethernet coupler.
|
||||||
|
|
||||||
### Going N-only
|
## Going N-only
|
||||||
|
|
||||||
The 802.11b to 802.11g migration was a mess; networks effectively dropped back to all-B in the presence of even a single B device. G to N isn't as bad, but it's not great; 802.11 continues to accumulate backwards-compatibility hacks all over the place. However, I was surprised to find that every device except my old T60 supports N, including my Nexus One. It didn't ship with the support, and Google never indicated that an upgrade to it was forthcoming, but it must have snuck out with a firmware upgrade somewhere. After digging out an old 802.11n mini-PCI card that I bought years ago and upgrading the T60, I was able to switch from G/N to just N. This is probably a significant win, if you can manage to upgrade all your devices. If not, confining the older ones to 2.4GHz (leaving 5GHz to pure-N, rather than A/N) is probably your best bet.
|
The 802.11b to 802.11g migration was a mess; networks effectively dropped back to all-B in the presence of even a single B device. G to N isn't as bad, but it's not great; 802.11 continues to accumulate backwards-compatibility hacks all over the place. However, I was surprised to find that every device except my old T60 supports N, including my Nexus One. It didn't ship with the support, and Google never indicated that an upgrade to it was forthcoming, but it must have snuck out with a firmware upgrade somewhere. After digging out an old 802.11n mini-PCI card that I bought years ago and upgrading the T60, I was able to switch from G/N to just N. This is probably a significant win, if you can manage to upgrade all your devices. If not, confining the older ones to 2.4GHz (leaving 5GHz to pure-N, rather than A/N) is probably your best bet.
|
||||||
|
|
||||||
### There's N, then there's N
|
## There's N, then there's N
|
||||||
|
|
||||||
802.11n has to be one of the most consumer-confusing specs ever. N works by using multiple antennas to build virtual "spatial streams". For example, radio one has antennas 1A and 1B; radio two has 2A, 2B and 2C. The silicon supports 2 spatial channels, which get built between, e.g. 1A and 2B, 1B and 2C. These spatial channels are treated as separate links, even though they're on the same frequency. There are 16 possible antenna/radio configurations and 30 antenna/radio/spatial channel configurations. The configurations are abbreviated AxB:C (A: transmit radios/antennas, B: receive radios/antennas, C: processor-supported spatial channels). The spec goes up to 4x4:4. Unfortunately, this means that 3-antenna systems aren't necessarily 3-stream (and most sold today aren't). You can't have more streams than your lowest radio/antenna count, and your maximum speed is determined by your number of streams and frequency width. N can use 20MHz or 40MHz of radio spectrum. The DIR-855 I bought seems to be either 2x3:2 or 3x3:2; 300mbit/s max at 40MHz. It seems to be impossible to buy 3- or 4-stream consumer gear at the moment (and you need client gear to support it, so it wouldn't be too useful).
|
802.11n has to be one of the most consumer-confusing specs ever. N works by using multiple antennas to build virtual "spatial streams". For example, radio one has antennas 1A and 1B; radio two has 2A, 2B and 2C. The silicon supports 2 spatial channels, which get built between, e.g. 1A and 2B, 1B and 2C. These spatial channels are treated as separate links, even though they're on the same frequency. There are 16 possible antenna/radio configurations and 30 antenna/radio/spatial channel configurations. The configurations are abbreviated AxB:C (A: transmit radios/antennas, B: receive radios/antennas, C: processor-supported spatial channels). The spec goes up to 4x4:4. Unfortunately, this means that 3-antenna systems aren't necessarily 3-stream (and most sold today aren't). You can't have more streams than your lowest radio/antenna count, and your maximum speed is determined by your number of streams and frequency width. N can use 20MHz or 40MHz of radio spectrum. The DIR-855 I bought seems to be either 2x3:2 or 3x3:2; 300mbit/s max at 40MHz. It seems to be impossible to buy 3- or 4-stream consumer gear at the moment (and you need client gear to support it, so it wouldn't be too useful).
|
||||||
|
|
||||||
### 2.4GHz vs. 5GHz
|
## 2.4GHz vs. 5GHz
|
||||||
|
|
||||||
802.11n makes the frequency choice even harder than it used to be. 2.4GHz is an overpopulated ghetto unless you live on double-digit acreage. It penetrates walls significantly better than 5GHz, but that's a blessing and a curse: you can use it from further away, but your neighbors interfere from further away. Even worse, at 40MHz, 802.11n takes 2 of the 3 non-overlapping 2.4GHz channels. That means that if you can see two or more neighboring access points, you're not getting full speed. The penetration advantages are significant, though: my iPad gets 6mbit/s link speed on 5GHz at the furthest point in my apartment from my access point. At 2.4GHz, it gets 26mbit/s.
|
802.11n makes the frequency choice even harder than it used to be. 2.4GHz is an overpopulated ghetto unless you live on double-digit acreage. It penetrates walls significantly better than 5GHz, but that's a blessing and a curse: you can use it from further away, but your neighbors interfere from further away. Even worse, at 40MHz, 802.11n takes 2 of the 3 non-overlapping 2.4GHz channels. That means that if you can see two or more neighboring access points, you're not getting full speed. The penetration advantages are significant, though: my iPad gets 6mbit/s link speed on 5GHz at the furthest point in my apartment from my access point. At 2.4GHz, it gets 26mbit/s.
|
||||||
|
|
||||||
Dual-band solutions help, but you have to be careful. Assign different SSIDs to your 2.4GHz and 5GHz networks, so you can force clients to one or the other. Put things like video streaming in 5GHz, where a neighbor download isn't likely to cause hiccups. Test your other devices at maximum range, and see whether you can live with the 5GHz signal level.
|
Dual-band solutions help, but you have to be careful. Assign different SSIDs to your 2.4GHz and 5GHz networks, so you can force clients to one or the other. Put things like video streaming in 5GHz, where a neighbor download isn't likely to cause hiccups. Test your other devices at maximum range, and see whether you can live with the 5GHz signal level.
|
||||||
|
|
||||||
### A little more range
|
## A little more range
|
||||||
|
|
||||||
If you'd like to squeak just a little more range out of your access point, either to be able to use 5GHz where you would've used 2.4GHz, or to be able to reach far-away spots with anything at all, consider replacement antennas. Higher-grade access points support them, and they'll buy you a little bit, though don't expect miracles. I picked up 3 of these, which help a bit without taking it to ridiculous extremes.
|
If you'd like to squeak just a little more range out of your access point, either to be able to use 5GHz where you would've used 2.4GHz, or to be able to reach far-away spots with anything at all, consider replacement antennas. Higher-grade access points support them, and they'll buy you a little bit, though don't expect miracles. I picked up 3 of these, which help a bit without taking it to ridiculous extremes.
|
||||||
|
|
||||||
### Other optimizations
|
## Other optimizations
|
||||||
|
|
||||||
Location, location, location: put your access point in the middle of your coverage area. It's the simplest thing you can do to get massive speed gains.
|
Location, location, location: put your access point in the middle of your coverage area. It's the simplest thing you can do to get massive speed gains.
|
||||||
|
|
||||||
|
|||||||
@@ -3,11 +3,11 @@
|
|||||||
|
|
||||||
<!--# include file="include/top.html" -->
|
<!--# include file="include/top.html" -->
|
||||||
|
|
||||||
### Choosing a platform
|
## Choosing a platform
|
||||||
|
|
||||||
There's no shortage of alternatives to the traditional cable box + TV model, from cable provider DVRs to [TiVo](http://www.tivo.com/) (yes, people actually still own those) to more obscure offerings like [Myka](http://www.myka.tv/), or [MythTV](http://www.mythtv.org/) running on your closest whitebox. However, if you want to combine easy content sourcing, central storage/management with streaming, a nice remote control interface and solid, attractive hardware, there's really only one option: for better or worse, Apple's [iTunes](http://www.apple.com/itunes/)/[Front Row](http://en.wikipedia.org/wiki/Front_Row_(software%29).
|
There's no shortage of alternatives to the traditional cable box + TV model, from cable provider DVRs to [TiVo](http://www.tivo.com/) (yes, people actually still own those) to more obscure offerings like [Myka](http://www.myka.tv/), or [MythTV](http://www.mythtv.org/) running on your closest whitebox. However, if you want to combine easy content sourcing, central storage/management with streaming, a nice remote control interface and solid, attractive hardware, there's really only one option: for better or worse, Apple's [iTunes](http://www.apple.com/itunes/)/[Front Row](http://en.wikipedia.org/wiki/Front_Row_(software%29).
|
||||||
|
|
||||||
### Electronics
|
## Electronics
|
||||||
|
|
||||||
I already had an iMac that had ended up at a common-area computer desk in my apartment. This seemed a reasonable choice for a media server, though I suppose I could've shot for something that had a concept of running headless (another [Mac Mini](http://www.apple.com/macmini/)).
|
I already had an iMac that had ended up at a common-area computer desk in my apartment. This seemed a reasonable choice for a media server, though I suppose I could've shot for something that had a concept of running headless (another [Mac Mini](http://www.apple.com/macmini/)).
|
||||||
|
|
||||||
@@ -15,23 +15,23 @@ Output streams to the TVs had two options: the Mac Mini, or an [Apple TV](http:/
|
|||||||
|
|
||||||
As actual displays, I went with [LED-backlit Samsung LCDs](http://www.samsung.com/us/consumer/tv-video/televisions/led-tv/UN40B7000WFUZA/index.idx?pagetype=prd_detail&returnurl=), for the lower power usage and the light weight for wall hanging. Add in [some](http://www.monoprice.com/products/product.asp?c_id=102&cp_id=10246&cs_id=1024603&p_id=5994&seq=1&format=2) [cables](http://www.monoprice.com/products/product.asp?c_id=102&cp_id=10218&cs_id=1021802&p_id=5576&seq=1&format=2) and we're good to go...except that it's all sitting on the floor.
|
As actual displays, I went with [LED-backlit Samsung LCDs](http://www.samsung.com/us/consumer/tv-video/televisions/led-tv/UN40B7000WFUZA/index.idx?pagetype=prd_detail&returnurl=), for the lower power usage and the light weight for wall hanging. Add in [some](http://www.monoprice.com/products/product.asp?c_id=102&cp_id=10246&cs_id=1024603&p_id=5994&seq=1&format=2) [cables](http://www.monoprice.com/products/product.asp?c_id=102&cp_id=10218&cs_id=1021802&p_id=5576&seq=1&format=2) and we're good to go...except that it's all sitting on the floor.
|
||||||
|
|
||||||
### Wall mounting
|
## Wall mounting
|
||||||
|
|
||||||
Fortunately, my two TVs were wall mount efforts #6 and 7 for Kacirek, so this went really smoothly. I picked up [wall mount kits](http://www.monoprice.com/products/product.asp?c_id=108&cp_id=10828&cs_id=1082812&p_id=5918&seq=1&format=2) from Monoprice. In short: stud finder, level, pilot holes, lag bolts, bolts to the TV, hang, done. There are even nice [wall mount kits for Mac Minis](http://www.amazon.com/gp/product/B000UWI2LC/ref=oss_product), naturally at more than twice the price of the LCD mounts, since they count as "designer". The Mac Mini power adapter fits really nicely in a cable-management cutout at the back of the TV. Add in an extension cord and some cable management from Fry's, and voila:
|
Fortunately, my two TVs were wall mount efforts #6 and 7 for Kacirek, so this went really smoothly. I picked up [wall mount kits](http://www.monoprice.com/products/product.asp?c_id=108&cp_id=10828&cs_id=1082812&p_id=5918&seq=1&format=2) from Monoprice. In short: stud finder, level, pilot holes, lag bolts, bolts to the TV, hang, done. There are even nice [wall mount kits for Mac Minis](http://www.amazon.com/gp/product/B000UWI2LC/ref=oss_product), naturally at more than twice the price of the LCD mounts, since they count as "designer". The Mac Mini power adapter fits really nicely in a cable-management cutout at the back of the TV. Add in an extension cord and some cable management from Fry's, and voila:
|
||||||
|
|
||||||
[images lost in Picasa shutdown]
|
[images lost in Picasa shutdown]
|
||||||
|
|
||||||
### Front Row love and hate
|
## Front Row love and hate
|
||||||
|
|
||||||
Front Row is, at times, awesome. It remembers pause position across different streaming clients. The interface is simple and useful. Over a fast network, seeking and fast-forward are lightning-quick. It doesn't let you set a default streaming source, but that only adds a couple of clicks.
|
Front Row is, at times, awesome. It remembers pause position across different streaming clients. The interface is simple and useful. Over a fast network, seeking and fast-forward are lightning-quick. It doesn't let you set a default streaming source, but that only adds a couple of clicks.
|
||||||
|
|
||||||
Sometimes, it's horribly frustrating. It hangs indefinitely and uninterruptably trying to load remote library contents. It forgets pause position, even on the same machine. None of these are repeatable, so trying to solve them seems nigh-impossible.
|
Sometimes, it's horribly frustrating. It hangs indefinitely and uninterruptably trying to load remote library contents. It forgets pause position, even on the same machine. None of these are repeatable, so trying to solve them seems nigh-impossible.
|
||||||
|
|
||||||
### Unofficial content
|
## Unofficial content
|
||||||
|
|
||||||
iTunes also doesn't want you using their fancy toys with torrented files; it won't let you add them to your library, and if you change the file type to work around that, it still won't stream them to remote clients. Fortunately, this is pretty simple to work around. You need [Quicktime Pro](http://www.apple.com/quicktime/pro/), which comes with Final Cut Studio, is cheap to buy separately, or can be obtained by whatever means you like. It hides in Utilities once installed, and is easy to confuse with Apple's stripped-down but base-install Quicktime Player. Follow steps 1-4 [here](http://www.apple.com/quicktime/tutorials/hinttracks.html), and your torrented content is now draggable into iTunes and streamable to Front Row clients. It doesn't re-encode unless you do steps 5-8, so it's fast and you don't lose quality.
|
iTunes also doesn't want you using their fancy toys with torrented files; it won't let you add them to your library, and if you change the file type to work around that, it still won't stream them to remote clients. Fortunately, this is pretty simple to work around. You need [Quicktime Pro](http://www.apple.com/quicktime/pro/), which comes with Final Cut Studio, is cheap to buy separately, or can be obtained by whatever means you like. It hides in Utilities once installed, and is easy to confuse with Apple's stripped-down but base-install Quicktime Player. Follow steps 1-4 [here](http://www.apple.com/quicktime/tutorials/hinttracks.html), and your torrented content is now draggable into iTunes and streamable to Front Row clients. It doesn't re-encode unless you do steps 5-8, so it's fast and you don't lose quality.
|
||||||
|
|
||||||
### Automatic wake-up
|
## Automatic wake-up
|
||||||
|
|
||||||
I also wanted waking up the Mini clients to automatically wake up the iMac file server, so I didn't have to leave it running all the time. Again, this isn't too hard. First, pick up [SleepWatcher](http://www.bernhard-baehr.de/), clearly written and packaged by someone who's never heard of dmg or a Makefile (but it works). Install [wakeonlan](http://gsd.di.uminho.pt/jpo/software/wakeonlan/), a tiny little PERL script that sends [Wake-on-LAN](http://en.wikipedia.org/wiki/Wake-on-LAN) magic packets. Then, add something to /etc/rc.wakeup like:
|
I also wanted waking up the Mini clients to automatically wake up the iMac file server, so I didn't have to leave it running all the time. Again, this isn't too hard. First, pick up [SleepWatcher](http://www.bernhard-baehr.de/), clearly written and packaged by someone who's never heard of dmg or a Makefile (but it works). Install [wakeonlan](http://gsd.di.uminho.pt/jpo/software/wakeonlan/), a tiny little PERL script that sends [Wake-on-LAN](http://en.wikipedia.org/wiki/Wake-on-LAN) magic packets. Then, add something to /etc/rc.wakeup like:
|
||||||
|
|
||||||
@@ -44,7 +44,7 @@ I also wanted waking up the Mini clients to automatically wake up the iMac file
|
|||||||
|
|
||||||
Your path to wakeonlan, MAC address (of your fileserver) and packet count (and time) required for your network interface to come online may vary.
|
Your path to wakeonlan, MAC address (of your fileserver) and packet count (and time) required for your network interface to come online may vary.
|
||||||
|
|
||||||
### Hello, iPad?
|
## Hello, iPad?
|
||||||
|
|
||||||
It would be really great to be able to pull a Minority Report-style video transfer, moving streaming video seamlessly from a TV to the iPad and walking away with it. This is a pipe dream, however, until Apple decides to actually support streaming on the iPad. Seriously, Apple, I have to plug this thing in and copy the whole video to it to watch it?
|
It would be really great to be able to pull a Minority Report-style video transfer, moving streaming video seamlessly from a TV to the iPad and walking away with it. This is a pipe dream, however, until Apple decides to actually support streaming on the iPad. Seriously, Apple, I have to plug this thing in and copy the whole video to it to watch it?
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ This is an in-depth dive into the actual observed behavior and interaction of ep
|
|||||||
|
|
||||||
I’ll be showing observed behavior through strace and tcpdump output.
|
I’ll be showing observed behavior through strace and tcpdump output.
|
||||||
|
|
||||||
### Setup
|
## Setup
|
||||||
|
|
||||||
Our test environment starts with two sockets connected to each other. There’s also a listening socket, only used to accept the initial connection, and an epoll fd. Both of the connected sockets are added to the epoll watch set, with most possible level-triggered flags enabled.
|
Our test environment starts with two sockets connected to each other. There’s also a listening socket, only used to accept the initial connection, and an epoll fd. Both of the connected sockets are added to the epoll watch set, with most possible level-triggered flags enabled.
|
||||||
|
|
||||||
@@ -37,7 +37,7 @@ On the wire, this is just a typical 3-way handshake:
|
|||||||
|
|
||||||
We now have two file descriptors, 5 and 6, that are opposite ends of the same TCP connection. They’re both in the epoll set of epoll file descriptor 3. They’re both signaling writability (EPOLLOUT), and nothing else. All is as expected.
|
We now have two file descriptors, 5 and 6, that are opposite ends of the same TCP connection. They’re both in the epoll set of epoll file descriptor 3. They’re both signaling writability (EPOLLOUT), and nothing else. All is as expected.
|
||||||
|
|
||||||
### shutdown(SHUT\_RD)
|
## shutdown(SHUT\_RD)
|
||||||
|
|
||||||
Now let’s call shutdown(5, SHUT\_RD).
|
Now let’s call shutdown(5, SHUT\_RD).
|
||||||
|
|
||||||
@@ -64,7 +64,7 @@ However, this doesn’t do anything on the wire. That means that the other side
|
|||||||
|
|
||||||
Side note: notice that close(5) causes automatic removal of that socket from the epoll set. This is handy, but see dup() below.
|
Side note: notice that close(5) causes automatic removal of that socket from the epoll set. This is handy, but see dup() below.
|
||||||
|
|
||||||
### shutdown(SHUT\_WR)
|
## shutdown(SHUT\_WR)
|
||||||
|
|
||||||
Let’s rewind and test with SHUT\_WR (write).
|
Let’s rewind and test with SHUT\_WR (write).
|
||||||
|
|
||||||
@@ -97,7 +97,7 @@ After shutdown(5, SHUT\_WR), fd 5 returns EPIPE and generates SIGPIPE if you wri
|
|||||||
|
|
||||||
The only oddity here is that calling close(5) doesn’t change any of the epoll status flags for fd 6. Once you attempt to write to fd 6, however, every flag on the planet starts firing, including EPOLLERR and EPOLLHUP.
|
The only oddity here is that calling close(5) doesn’t change any of the epoll status flags for fd 6. Once you attempt to write to fd 6, however, every flag on the planet starts firing, including EPOLLERR and EPOLLHUP.
|
||||||
|
|
||||||
### dup()
|
## dup()
|
||||||
|
|
||||||
Rewinding to our setup state again, let’s look at dup().
|
Rewinding to our setup state again, let’s look at dup().
|
||||||
|
|
||||||
@@ -126,7 +126,7 @@ dup(5) gives us the new fd 7. We add it to the set, and all looks normal. We wri
|
|||||||
|
|
||||||
Here’s crazy town, though. close(5) doesn’t remove it from the epoll set. epoll is waiting for the underlying socket to close, and fd 7’s existence is keeping it alive. Trying to remove fd 5 from the epoll set also fails. The only way to get rid of it seems to be to close(7), which removes both from the set and causes fd 6 to signal EPOLLIN and EPOLLRDHUP.
|
Here’s crazy town, though. close(5) doesn’t remove it from the epoll set. epoll is waiting for the underlying socket to close, and fd 7’s existence is keeping it alive. Trying to remove fd 5 from the epoll set also fails. The only way to get rid of it seems to be to close(7), which removes both from the set and causes fd 6 to signal EPOLLIN and EPOLLRDHUP.
|
||||||
|
|
||||||
### shutdown(SHUT\_RD) + dup()
|
## shutdown(SHUT\_RD) + dup()
|
||||||
|
|
||||||
dup(5) = 7
|
dup(5) = 7
|
||||||
epoll_ctl(3, EPOLL_CTL_ADD, 7, {EPOLLIN|EPOLLOUT|EPOLLERR|EPOLLHUP|EPOLLRDHUP, {u32=7, u64=7}}) = 0
|
epoll_ctl(3, EPOLL_CTL_ADD, 7, {EPOLLIN|EPOLLOUT|EPOLLERR|EPOLLHUP|EPOLLRDHUP, {u32=7, u64=7}}) = 0
|
||||||
@@ -138,7 +138,7 @@ Nothing extra traverses the wire.
|
|||||||
|
|
||||||
The takeaway here is that shutdown() operates on the underlying socket endpoint, not the file descriptor. Calling shutdown(7, SHUT\_RD) causes both fd 5 and 7 to signal EPOLLIN and EPOLLRDHUP.
|
The takeaway here is that shutdown() operates on the underlying socket endpoint, not the file descriptor. Calling shutdown(7, SHUT\_RD) causes both fd 5 and 7 to signal EPOLLIN and EPOLLRDHUP.
|
||||||
|
|
||||||
### shutdown(SHUT\_WR) + dup()
|
## shutdown(SHUT\_WR) + dup()
|
||||||
|
|
||||||
dup(5) = 7
|
dup(5) = 7
|
||||||
epoll_ctl(3, EPOLL_CTL_ADD, 7, {EPOLLIN|EPOLLOUT|EPOLLERR|EPOLLHUP|EPOLLRDHUP, {u32=7, u64=7}}) = 0
|
epoll_ctl(3, EPOLL_CTL_ADD, 7, {EPOLLIN|EPOLLOUT|EPOLLERR|EPOLLHUP|EPOLLRDHUP, {u32=7, u64=7}}) = 0
|
||||||
@@ -153,7 +153,7 @@ The takeaway here is that shutdown() operates on the underlying socket endpoint,
|
|||||||
|
|
||||||
As expected, shutdown(7, SHUT\_WR) causes fd 6 to signal EPOLLIN and EPOLLRDHUP.
|
As expected, shutdown(7, SHUT\_WR) causes fd 6 to signal EPOLLIN and EPOLLRDHUP.
|
||||||
|
|
||||||
### Conclusions
|
## Conclusions
|
||||||
|
|
||||||
* If you’re using dup() and epoll, you need to call epoll\_ctl(EPOLL\_CTL\_DEL) before calling close(). It’s hard to imagine getting sane behavior any other way. If you never use dup(), you can just call close().
|
* If you’re using dup() and epoll, you need to call epoll\_ctl(EPOLL\_CTL\_DEL) before calling close(). It’s hard to imagine getting sane behavior any other way. If you never use dup(), you can just call close().
|
||||||
* If you’re using dup() and epoll and want to signal all fds on a socket to close, you can call shutdown(SHUT\_RD) before calling close(), causing EPOLLRDHUP to signal for other fds attached to the same socket.
|
* If you’re using dup() and epoll and want to signal all fds on a socket to close, you can call shutdown(SHUT\_RD) before calling close(), causing EPOLLRDHUP to signal for other fds attached to the same socket.
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
Down another rabbit hole, this time into yet another seemingly simple problem: how do you turn a name into an address that you can connect() to without blocking your thread, in 2016. Let’s survey state of the world:
|
Down another rabbit hole, this time into yet another seemingly simple problem: how do you turn a name into an address that you can connect() to without blocking your thread, in 2016. Let’s survey state of the world:
|
||||||
|
|
||||||
### [getaddrinfo\_a()](http://man7.org/linux/man-pages/man3/getaddrinfo_a.3.html)
|
## [getaddrinfo\_a()](http://man7.org/linux/man-pages/man3/getaddrinfo_a.3.html)
|
||||||
|
|
||||||
Look, it’s exactly what we need! Just joking. It’s has the same resolution behavior as getaddrinfo, but:
|
Look, it’s exactly what we need! Just joking. It’s has the same resolution behavior as getaddrinfo, but:
|
||||||
|
|
||||||
@@ -13,19 +13,19 @@ Look, it’s exactly what we need! Just joking. It’s has the same resolution b
|
|||||||
* It allocates memory and gives you no way to free it. Calling freeaddrinfo() doesn’t do it. The manpage doesn’t even seem to consider that one might want to free memory. It’s possible that it’s a first-time-only allocation that hasn’t made it into valgrind’s default suppressions yet.
|
* It allocates memory and gives you no way to free it. Calling freeaddrinfo() doesn’t do it. The manpage doesn’t even seem to consider that one might want to free memory. It’s possible that it’s a first-time-only allocation that hasn’t made it into valgrind’s default suppressions yet.
|
||||||
* It uses [sigevent](http://man7.org/linux/man-pages/man7/sigevent.7.html) to notify completion. This gives you a choice between a signal and a new thread. I thought we were doing this to avoid having to create a new thread for each resolution?
|
* It uses [sigevent](http://man7.org/linux/man-pages/man7/sigevent.7.html) to notify completion. This gives you a choice between a signal and a new thread. I thought we were doing this to avoid having to create a new thread for each resolution?
|
||||||
|
|
||||||
### [libadns](http://www.gnu.org/software/adns/)
|
## [libadns](http://www.gnu.org/software/adns/)
|
||||||
|
|
||||||
* It’s GPLed. That’s cool, but it does limit options.
|
* It’s GPLed. That’s cool, but it does limit options.
|
||||||
* It’s a direct DNS library, not a getaddrinfo() implementation. That means you have to reproduce all the getaddrinfo() behavior, including the configuration file, if you want the behavior that users expect.
|
* It’s a direct DNS library, not a getaddrinfo() implementation. That means you have to reproduce all the getaddrinfo() behavior, including the configuration file, if you want the behavior that users expect.
|
||||||
* It will hand you file descriptors to block on, but you have to ask (using adns\_beforeselect()). This is designed for poll(), but doesn’t work well with epoll; it doesn’t tell you when to add and remove fds, so you have to track them yourself (since you can’t iterate an epoll set), diff them since the last result, and change the epoll set. It’s a mess.
|
* It will hand you file descriptors to block on, but you have to ask (using adns\_beforeselect()). This is designed for poll(), but doesn’t work well with epoll; it doesn’t tell you when to add and remove fds, so you have to track them yourself (since you can’t iterate an epoll set), diff them since the last result, and change the epoll set. It’s a mess.
|
||||||
|
|
||||||
### [libasyncns](http://0pointer.de/lennart/projects/libasyncns/)
|
## [libasyncns](http://0pointer.de/lennart/projects/libasyncns/)
|
||||||
|
|
||||||
* It uses getaddrinfo() underneath, so you get standard behavior. Woo!
|
* It uses getaddrinfo() underneath, so you get standard behavior. Woo!
|
||||||
* It notifies you via a file descriptor. Unfortunately, it’s only a single file descriptor across all requests. It doesn’t allow you to associate a pointer with a request, epoll-style, so you still have to track your own query list and higher-level data associations.
|
* It notifies you via a file descriptor. Unfortunately, it’s only a single file descriptor across all requests. It doesn’t allow you to associate a pointer with a request, epoll-style, so you still have to track your own query list and higher-level data associations.
|
||||||
* Its API isn’t too crazy, but you wouldn’t call it simple.
|
* Its API isn’t too crazy, but you wouldn’t call it simple.
|
||||||
|
|
||||||
### [c-ares](http://c-ares.haxx.se/)
|
## [c-ares](http://c-ares.haxx.se/)
|
||||||
|
|
||||||
I failed to find docs for this, but I found a gist with an [example](https://gist.github.com/mopemope/992777). Looks like the API is designed for use with select(), though there’s a hook to get an fd when it’s created, so you might be able to associate it with a query, possibly unreliably. Again, you’d have to recreate getaddrinfo() behavior yourself. Also, this gem is at the top of the header:
|
I failed to find docs for this, but I found a gist with an [example](https://gist.github.com/mopemope/992777). Looks like the API is designed for use with select(), though there’s a hook to get an fd when it’s created, so you might be able to associate it with a query, possibly unreliably. Again, you’d have to recreate getaddrinfo() behavior yourself. Also, this gem is at the top of the header:
|
||||||
|
|
||||||
@@ -39,7 +39,7 @@ I failed to find docs for this, but I found a gist with an [example](https://gis
|
|||||||
|
|
||||||
So maybe not.
|
So maybe not.
|
||||||
|
|
||||||
### So now what?
|
## So now what?
|
||||||
|
|
||||||
Maybe we can build something. I really don’t need to write another DNS library in my lifetime (the c-ares [Other Libraries](http://c-ares.haxx.se/otherlibs.html) page links to my previous one, humorously). Let’s see if we can scope some requirements:
|
Maybe we can build something. I really don’t need to write another DNS library in my lifetime (the c-ares [Other Libraries](http://c-ares.haxx.se/otherlibs.html) page links to my previous one, humorously). Let’s see if we can scope some requirements:
|
||||||
|
|
||||||
|
|||||||
@@ -11,31 +11,31 @@ I should really script this.
|
|||||||
|
|
||||||
Start with [Raspbian Lite](https://www.raspberrypi.org/downloads/raspbian/). NOOBS has an extra boot step, and Raspbian full version has a GUI and stuff like Wolfram Engine that you probably don’t want.
|
Start with [Raspbian Lite](https://www.raspberrypi.org/downloads/raspbian/). NOOBS has an extra boot step, and Raspbian full version has a GUI and stuff like Wolfram Engine that you probably don’t want.
|
||||||
|
|
||||||
### Log in
|
## Log in
|
||||||
|
|
||||||
Use console, or grab the IP from your router’s DHCP client list and:
|
Use console, or grab the IP from your router’s DHCP client list and:
|
||||||
|
|
||||||
ssh pi@<ip address>
|
ssh pi@<ip address>
|
||||||
# password "raspberry"
|
# password "raspberry"
|
||||||
|
|
||||||
### Expand filesystem
|
## Expand filesystem
|
||||||
|
|
||||||
sudo raspi-config --expand-rootfs
|
sudo raspi-config --expand-rootfs
|
||||||
sudo reboot
|
sudo reboot
|
||||||
|
|
||||||
Wait for reboot. Reconnect as above.
|
Wait for reboot. Reconnect as above.
|
||||||
|
|
||||||
### Update
|
## Update
|
||||||
|
|
||||||
sudo apt-get -y update
|
sudo apt-get -y update
|
||||||
sudo apt-get -y dist-upgrade
|
sudo apt-get -y dist-upgrade
|
||||||
|
|
||||||
### Update firmware
|
## Update firmware
|
||||||
|
|
||||||
sudo apt-get -y install rpi-update
|
sudo apt-get -y install rpi-update
|
||||||
sudo rpi-update
|
sudo rpi-update
|
||||||
|
|
||||||
### Enable overclock (optional)
|
## Enable overclock (optional)
|
||||||
|
|
||||||
Pis seem to be relatively stable overclocked, even without a heatsink.
|
Pis seem to be relatively stable overclocked, even without a heatsink.
|
||||||
|
|
||||||
@@ -47,17 +47,17 @@ Pis seem to be relatively stable overclocked, even without a heatsink.
|
|||||||
# Select "<Finish>"
|
# Select "<Finish>"
|
||||||
# Select "<No>"
|
# Select "<No>"
|
||||||
|
|
||||||
### Disable swap
|
## Disable swap
|
||||||
|
|
||||||
sudo dphys-swapfile uninstall
|
sudo dphys-swapfile uninstall
|
||||||
|
|
||||||
### Create a new user
|
## Create a new user
|
||||||
|
|
||||||
sudo adduser <username>
|
sudo adduser <username>
|
||||||
# Follow prompts
|
# Follow prompts
|
||||||
sudo usermod --append --groups sudo <username>
|
sudo usermod --append --groups sudo <username>
|
||||||
|
|
||||||
### SSH in as the new user
|
## SSH in as the new user
|
||||||
|
|
||||||
# ON YOUR PI
|
# ON YOUR PI
|
||||||
# Find your Pi's current IP, you don't know it
|
# Find your Pi's current IP, you don't know it
|
||||||
@@ -74,7 +74,7 @@ Pis seem to be relatively stable overclocked, even without a heatsink.
|
|||||||
# Connect to your Pi; this should NOT ask for a password
|
# Connect to your Pi; this should NOT ask for a password
|
||||||
ssh <username>@<ip>
|
ssh <username>@<ip>
|
||||||
|
|
||||||
### Lock down sshd
|
## Lock down sshd
|
||||||
|
|
||||||
The SSH server has a lot of options turned on by default for compatibility with a wide range of clients. If you’re connecting only from modern machines, and you’ve gotten public key authentication working as described above (and tested it!), then you can turn off lots of the legacy options.
|
The SSH server has a lot of options turned on by default for compatibility with a wide range of clients. If you’re connecting only from modern machines, and you’ve gotten public key authentication working as described above (and tested it!), then you can turn off lots of the legacy options.
|
||||||
|
|
||||||
@@ -112,7 +112,7 @@ The SSH server has a lot of options turned on by default for compatibility with
|
|||||||
END
|
END
|
||||||
# Enter password for sudo
|
# Enter password for sudo
|
||||||
|
|
||||||
### Enable the hardware random number generator
|
## Enable the hardware random number generator
|
||||||
|
|
||||||
Note that hardware random number generators [are controversial](https://en.wikipedia.org/wiki/RdRand#Reception).
|
Note that hardware random number generators [are controversial](https://en.wikipedia.org/wiki/RdRand#Reception).
|
||||||
|
|
||||||
@@ -120,7 +120,7 @@ Note that hardware random number generators [are controversial](https://en.wikip
|
|||||||
echo bcm2835_rng | sudo tee --append /etc/modules
|
echo bcm2835_rng | sudo tee --append /etc/modules
|
||||||
sudo apt-get -y install rng-tools
|
sudo apt-get -y install rng-tools
|
||||||
|
|
||||||
### Enable the hardware watchdog
|
## Enable the hardware watchdog
|
||||||
|
|
||||||
This has false negatives (failures to reboot when it should) for me, but never false positives.
|
This has false negatives (failures to reboot when it should) for me, but never false positives.
|
||||||
|
|
||||||
@@ -129,25 +129,25 @@ This has false negatives (failures to reboot when it should) for me, but never f
|
|||||||
watchdog-device = /dev/watchdog
|
watchdog-device = /dev/watchdog
|
||||||
END
|
END
|
||||||
|
|
||||||
### Enable automatic updates
|
## Enable automatic updates
|
||||||
|
|
||||||
sudo apt-get -y install unattended-upgrades
|
sudo apt-get -y install unattended-upgrades
|
||||||
sudo dpkg-reconfigure -plow unattended-upgrades
|
sudo dpkg-reconfigure -plow unattended-upgrades
|
||||||
# Choose "<Yes>"
|
# Choose "<Yes>"
|
||||||
|
|
||||||
### Disable avahi
|
## Disable avahi
|
||||||
|
|
||||||
You didn’t need mdns, did you?
|
You didn’t need mdns, did you?
|
||||||
|
|
||||||
sudo systemctl disable avahi-daemon.service
|
sudo systemctl disable avahi-daemon.service
|
||||||
|
|
||||||
### Disable triggerhappy
|
## Disable triggerhappy
|
||||||
|
|
||||||
You didn’t need volume buttons, did you?
|
You didn’t need volume buttons, did you?
|
||||||
|
|
||||||
sudo systemctl disable triggerhappy.service
|
sudo systemctl disable triggerhappy.service
|
||||||
|
|
||||||
### Disable frequency scaling
|
## Disable frequency scaling
|
||||||
|
|
||||||
If you’re not planning to run on battery; this thing is slow enough anyway.
|
If you’re not planning to run on battery; this thing is slow enough anyway.
|
||||||
|
|
||||||
@@ -156,7 +156,7 @@ If you’re not planning to run on battery; this thing is slow enough anyway.
|
|||||||
GOVERNOR="performance"
|
GOVERNOR="performance"
|
||||||
END
|
END
|
||||||
|
|
||||||
### Enable lldpd
|
## Enable lldpd
|
||||||
|
|
||||||
This allows you to observe network topology if you have managed switches.
|
This allows you to observe network topology if you have managed switches.
|
||||||
|
|
||||||
@@ -165,25 +165,25 @@ This allows you to observe network topology if you have managed switches.
|
|||||||
DAEMON_ARGS="-c"
|
DAEMON_ARGS="-c"
|
||||||
END
|
END
|
||||||
|
|
||||||
### Remove the pi user
|
## Remove the pi user
|
||||||
|
|
||||||
Well-known username, well-known password, no thank you.
|
Well-known username, well-known password, no thank you.
|
||||||
|
|
||||||
sudo deluser pi
|
sudo deluser pi
|
||||||
|
|
||||||
### Install busybox-syslogd
|
## Install busybox-syslogd
|
||||||
|
|
||||||
You give up persistent syslogs, but you reduce SD writes. You can still run “logread” to read logs since boot from RAM.
|
You give up persistent syslogs, but you reduce SD writes. You can still run “logread” to read logs since boot from RAM.
|
||||||
|
|
||||||
sudo apt-get -y install busybox-syslogd
|
sudo apt-get -y install busybox-syslogd
|
||||||
|
|
||||||
### Reboot
|
## Reboot
|
||||||
|
|
||||||
Test that changes work, and have some (disabling auto-login) take effect.
|
Test that changes work, and have some (disabling auto-login) take effect.
|
||||||
|
|
||||||
sudo reboot
|
sudo reboot
|
||||||
|
|
||||||
### After reboot
|
## After reboot
|
||||||
|
|
||||||
Note that ssh may scream “REMOTE HOST IDENTIFICATION HAS CHANGED!”; that’s a symptom of the sshd\_config changes above. Just remove the line from the known\_hosts file and reconnect.
|
Note that ssh may scream “REMOTE HOST IDENTIFICATION HAS CHANGED!”; that’s a symptom of the sshd\_config changes above. Just remove the line from the known\_hosts file and reconnect.
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ If you search for this on the Internets, you discover a problem. While 802.11 lo
|
|||||||
|
|
||||||
If you’ve got a router at the front of your network that supports static routes, though, you’ve got a conceptually simpler option: build a wireless client router. This is still a lot of moving parts and things to go wrong, but those things are going to be more debuggable when they do.
|
If you’ve got a router at the front of your network that supports static routes, though, you’ve got a conceptually simpler option: build a wireless client router. This is still a lot of moving parts and things to go wrong, but those things are going to be more debuggable when they do.
|
||||||
|
|
||||||
### Shopping list
|
## Shopping list
|
||||||
|
|
||||||
* [Raspberry Pi 2 Model B](http://www.amazon.com/Raspberry-Pi-Model-Project-Board/dp/B00T2U7R7I). This probably works fine with a Pi 3; I just haven’t tested it.
|
* [Raspberry Pi 2 Model B](http://www.amazon.com/Raspberry-Pi-Model-Project-Board/dp/B00T2U7R7I). This probably works fine with a Pi 3; I just haven’t tested it.
|
||||||
* A case of some sort. [This one](http://www.amazon.com/gp/product/B00S4H4ZTS) is my current preference (and I’ve tested rather a lot of them), for a nice balance of protection, heat dissipation, cost, and simplicity.
|
* A case of some sort. [This one](http://www.amazon.com/gp/product/B00S4H4ZTS) is my current preference (and I’ve tested rather a lot of them), for a nice balance of protection, heat dissipation, cost, and simplicity.
|
||||||
@@ -25,7 +25,7 @@ If you’ve got a router at the front of your network that supports static route
|
|||||||
|
|
||||||
[Install and configure Raspbian Lite](https://dev.firestuff.org/firestuff/2016-03-13-raspbian-setup-notes.html). [Get your device connected via WiFi](https://wiki.archlinux.org/index.php/WPA_supplicant). (Side note: the ArchLinux wiki is really great).
|
[Install and configure Raspbian Lite](https://dev.firestuff.org/firestuff/2016-03-13-raspbian-setup-notes.html). [Get your device connected via WiFi](https://wiki.archlinux.org/index.php/WPA_supplicant). (Side note: the ArchLinux wiki is really great).
|
||||||
|
|
||||||
### Assign a static IPv4 address
|
## Assign a static IPv4 address
|
||||||
|
|
||||||
Your wired side is going to need static addresses. These should be a different subnet than your existing private network. Strangely, in the new world, we configure static IPv4 addresses in /etc/dhcpcd.conf. Add a stanza that looks like:
|
Your wired side is going to need static addresses. These should be a different subnet than your existing private network. Strangely, in the new world, we configure static IPv4 addresses in /etc/dhcpcd.conf. Add a stanza that looks like:
|
||||||
|
|
||||||
@@ -34,7 +34,7 @@ Your wired side is going to need static addresses. These should be a different s
|
|||||||
nolink
|
nolink
|
||||||
noipv6rs
|
noipv6rs
|
||||||
|
|
||||||
### Assign a static IPv6 address
|
## Assign a static IPv6 address
|
||||||
|
|
||||||
You’ll need IPv6 addresses. These are going to be hard to keep in sync with IPv6 addresses on your main network; multi-level [prefix delegation](https://en.wikipedia.org/wiki/Prefix_delegation) does not seem to be a thing yet, though that’s likely the future. In the meantime, set up unique local addresses so you can at least talk within your network. Go [generate a unique local address block](https://www.ultratools.com/tools/rangeGenerator) to start with. Take the first address from that network (network::1) and configure it, this time in /etc/network/interfaces:
|
You’ll need IPv6 addresses. These are going to be hard to keep in sync with IPv6 addresses on your main network; multi-level [prefix delegation](https://en.wikipedia.org/wiki/Prefix_delegation) does not seem to be a thing yet, though that’s likely the future. In the meantime, set up unique local addresses so you can at least talk within your network. Go [generate a unique local address block](https://www.ultratools.com/tools/rangeGenerator) to start with. Take the first address from that network (network::1) and configure it, this time in /etc/network/interfaces:
|
||||||
|
|
||||||
@@ -48,7 +48,7 @@ You’ll need IPv6 addresses. These are going to be hard to keep in sync with IP
|
|||||||
|
|
||||||
Really, don’t just use the address from this page; generate your own.
|
Really, don’t just use the address from this page; generate your own.
|
||||||
|
|
||||||
### Enable router advertisements
|
## Enable router advertisements
|
||||||
|
|
||||||
sudo apt-get -y install radvd
|
sudo apt-get -y install radvd
|
||||||
|
|
||||||
@@ -65,7 +65,7 @@ Add a stanza to /etc/radvd.conf that looks like:
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
### Enable IP forwarding
|
## Enable IP forwarding
|
||||||
|
|
||||||
Edit /etc/sysctl.conf and uncomment the lines:
|
Edit /etc/sysctl.conf and uncomment the lines:
|
||||||
|
|
||||||
@@ -73,7 +73,7 @@ Edit /etc/sysctl.conf and uncomment the lines:
|
|||||||
|
|
||||||
net.ipv6.conf.all.forwarding=1
|
net.ipv6.conf.all.forwarding=1
|
||||||
|
|
||||||
### Set up a DHCP server
|
## Set up a DHCP server
|
||||||
|
|
||||||
sudo apt-get -y install isc-dhcp-server
|
sudo apt-get -y install isc-dhcp-server
|
||||||
|
|
||||||
@@ -90,7 +90,7 @@ Edit /etc/dhcp/dhcpd.conf, comment out the example junk, and add:
|
|||||||
option routers 10.167.0.1;
|
option routers 10.167.0.1;
|
||||||
}
|
}
|
||||||
|
|
||||||
### Static IP and route
|
## Static IP and route
|
||||||
|
|
||||||
Now you need to assign a static IPv4 address to the wireless interface of the machine, and create static routes for both IPv4 and IPv6. You should do both of these in your primary router; Google for instructions. The examples below are for Cisco IOS, which is likely not very useful to you.
|
Now you need to assign a static IPv4 address to the wireless interface of the machine, and create static routes for both IPv4 and IPv6. You should do both of these in your primary router; Google for instructions. The examples below are for Cisco IOS, which is likely not very useful to you.
|
||||||
|
|
||||||
@@ -102,11 +102,11 @@ Now you need to assign a static IPv4 address to the wireless interface of the ma
|
|||||||
|
|
||||||
ipv6 route FD8B:CF21:31AC:69DF::/64 FD8B:CF21:31AC:A8CD:AD7F:4B19:EBD9:34CB
|
ipv6 route FD8B:CF21:31AC:69DF::/64 FD8B:CF21:31AC:A8CD:AD7F:4B19:EBD9:34CB
|
||||||
|
|
||||||
### Reboot
|
## Reboot
|
||||||
|
|
||||||
Reboot your RPi to pick up all these changes.
|
Reboot your RPi to pick up all these changes.
|
||||||
|
|
||||||
### Caveats
|
## Caveats
|
||||||
|
|
||||||
Because of the lack of multi-level prefix delegation, hosts behind your new router won’t have IPv6 connectivity to the world. Fingers crossed to fix this soon.
|
Because of the lack of multi-level prefix delegation, hosts behind your new router won’t have IPv6 connectivity to the world. Fingers crossed to fix this soon.
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
Notes from setting up a two-level (root and intermediate) CA using EC certs, combined from two decent sets of instructions [here](https://jamielinux.com/docs/openssl-certificate-authority/introduction.html) and [here](https://wiki.openssl.org/index.php/Command_Line_Elliptic_Curve_Operations). This is the CliffsNotes version; see those two docs for more detail. XXXX is used as a placeholder here; search for it and replace.
|
Notes from setting up a two-level (root and intermediate) CA using EC certs, combined from two decent sets of instructions [here](https://jamielinux.com/docs/openssl-certificate-authority/introduction.html) and [here](https://wiki.openssl.org/index.php/Command_Line_Elliptic_Curve_Operations). This is the CliffsNotes version; see those two docs for more detail. XXXX is used as a placeholder here; search for it and replace.
|
||||||
|
|
||||||
### Create directory structure
|
## Create directory structure
|
||||||
|
|
||||||
mkdir ca
|
mkdir ca
|
||||||
cd ca
|
cd ca
|
||||||
@@ -132,19 +132,19 @@ Notes from setting up a two-level (root and intermediate) CA using EC certs, com
|
|||||||
extendedKeyUsage = critical, OCSPSigning
|
extendedKeyUsage = critical, OCSPSigning
|
||||||
END
|
END
|
||||||
|
|
||||||
### Create a root key
|
## Create a root key
|
||||||
|
|
||||||
openssl ecparam -name secp384r1 -genkey | openssl ec -aes-256-cbc -out root/private/root.key.pem
|
openssl ecparam -name secp384r1 -genkey | openssl ec -aes-256-cbc -out root/private/root.key.pem
|
||||||
# Create strong root key password
|
# Create strong root key password
|
||||||
chmod 400 root/private/root.key.pem
|
chmod 400 root/private/root.key.pem
|
||||||
|
|
||||||
### Create a self-signed root cert
|
## Create a self-signed root cert
|
||||||
|
|
||||||
openssl req -config openssl.cnf -key root/private/root.key.pem -new -extensions ext_root -out root/certs/root.cert.pem -x509 -subj '/C=US/ST=California/O=XXXX/OU=XXXX Certificate Authority/CN=XXXX Root CA' -days 7300
|
openssl req -config openssl.cnf -key root/private/root.key.pem -new -extensions ext_root -out root/certs/root.cert.pem -x509 -subj '/C=US/ST=California/O=XXXX/OU=XXXX Certificate Authority/CN=XXXX Root CA' -days 7300
|
||||||
# Enter root key password
|
# Enter root key password
|
||||||
chmod 444 root/certs/root.cert.pem
|
chmod 444 root/certs/root.cert.pem
|
||||||
|
|
||||||
### Verify root cert
|
## Verify root cert
|
||||||
|
|
||||||
openssl x509 -noout -text -in root/certs/root.cert.pem
|
openssl x509 -noout -text -in root/certs/root.cert.pem
|
||||||
|
|
||||||
@@ -155,24 +155,24 @@ Check:
|
|||||||
* Public key size (384 bit)
|
* Public key size (384 bit)
|
||||||
* CA:TRUE
|
* CA:TRUE
|
||||||
|
|
||||||
### Create an intermediate key
|
## Create an intermediate key
|
||||||
|
|
||||||
openssl ecparam -name secp384r1 -genkey | openssl ec -aes-256-cbc -out intermediate/private/intermediate.key.pem
|
openssl ecparam -name secp384r1 -genkey | openssl ec -aes-256-cbc -out intermediate/private/intermediate.key.pem
|
||||||
# Create strong intermediate key password
|
# Create strong intermediate key password
|
||||||
chmod 400 intermediate/private/intermediate.key.pem
|
chmod 400 intermediate/private/intermediate.key.pem
|
||||||
|
|
||||||
### Create an intermediate certificate signing request (CSR)
|
## Create an intermediate certificate signing request (CSR)
|
||||||
|
|
||||||
openssl req -config openssl.cnf -new -key intermediate/private/intermediate.key.pem -out intermediate/csr/intermediate.csr.pem -subj '/C=US/ST=California/O=XXXX/OU=XXXX Certificate Authority/CN=XXXX Intermediate'
|
openssl req -config openssl.cnf -new -key intermediate/private/intermediate.key.pem -out intermediate/csr/intermediate.csr.pem -subj '/C=US/ST=California/O=XXXX/OU=XXXX Certificate Authority/CN=XXXX Intermediate'
|
||||||
# Enter intermediate key password
|
# Enter intermediate key password
|
||||||
|
|
||||||
### Sign intermediate cert with root key
|
## Sign intermediate cert with root key
|
||||||
|
|
||||||
openssl ca -config openssl.cnf -name ca_root -extensions ext_intermediate -notext -in intermediate/csr/intermediate.csr.pem -out intermediate/certs/intermediate.cert.pem
|
openssl ca -config openssl.cnf -name ca_root -extensions ext_intermediate -notext -in intermediate/csr/intermediate.csr.pem -out intermediate/certs/intermediate.cert.pem
|
||||||
# Enter root key password
|
# Enter root key password
|
||||||
chmod 444 intermediate/certs/intermediate.cert.pem
|
chmod 444 intermediate/certs/intermediate.cert.pem
|
||||||
|
|
||||||
### Verify intermediate cert
|
## Verify intermediate cert
|
||||||
|
|
||||||
openssl x509 -noout -text -in intermediate/certs/intermediate.cert.pem
|
openssl x509 -noout -text -in intermediate/certs/intermediate.cert.pem
|
||||||
openssl verify -CAfile root/certs/root.cert.pem intermediate/certs/intermediate.cert.pem
|
openssl verify -CAfile root/certs/root.cert.pem intermediate/certs/intermediate.cert.pem
|
||||||
@@ -185,12 +185,12 @@ Check:
|
|||||||
* CA:TRUE
|
* CA:TRUE
|
||||||
* OK
|
* OK
|
||||||
|
|
||||||
### Create a chain certificate file
|
## Create a chain certificate file
|
||||||
|
|
||||||
cat intermediate/certs/intermediate.cert.pem root/certs/root.cert.pem > intermediate/certs/chain.cert.pem
|
cat intermediate/certs/intermediate.cert.pem root/certs/root.cert.pem > intermediate/certs/chain.cert.pem
|
||||||
chmod 444 intermediate/certs/chain.cert.pem
|
chmod 444 intermediate/certs/chain.cert.pem
|
||||||
|
|
||||||
### Create a client key
|
## Create a client key
|
||||||
|
|
||||||
You can substitute “server” for “client” for a server cert.
|
You can substitute “server” for “client” for a server cert.
|
||||||
|
|
||||||
@@ -198,17 +198,17 @@ You can substitute “server” for “client” for a server cert.
|
|||||||
# Create client key password
|
# Create client key password
|
||||||
chmod 400 client/private/test1.key.pem
|
chmod 400 client/private/test1.key.pem
|
||||||
|
|
||||||
### Create a client certificate signing request (CSR)
|
## Create a client certificate signing request (CSR)
|
||||||
|
|
||||||
openssl req -config openssl.cnf -new -key client/private/test1.key.pem -out client/csr/test1.csr.pem -subj '/C=US/ST=California/O=XXXX/OU=XXXX Test/CN=XXXX Test 1'
|
openssl req -config openssl.cnf -new -key client/private/test1.key.pem -out client/csr/test1.csr.pem -subj '/C=US/ST=California/O=XXXX/OU=XXXX Test/CN=XXXX Test 1'
|
||||||
|
|
||||||
### Sign client cert with intermediate key
|
## Sign client cert with intermediate key
|
||||||
|
|
||||||
openssl ca -config openssl.cnf -extensions ext_client -notext -in client/csr/test1.csr.pem -out client/certs/test1.cert.pem
|
openssl ca -config openssl.cnf -extensions ext_client -notext -in client/csr/test1.csr.pem -out client/certs/test1.cert.pem
|
||||||
# Enter intermediate key password
|
# Enter intermediate key password
|
||||||
chmod 444 client/certs/test1.cert.pem
|
chmod 444 client/certs/test1.cert.pem
|
||||||
|
|
||||||
### Verify client cert
|
## Verify client cert
|
||||||
|
|
||||||
openssl x509 -noout -text -in client/certs/test1.cert.pem
|
openssl x509 -noout -text -in client/certs/test1.cert.pem
|
||||||
openssl verify -CAfile intermediate/certs/chain.cert.pem client/certs/test1.cert.pem
|
openssl verify -CAfile intermediate/certs/chain.cert.pem client/certs/test1.cert.pem
|
||||||
@@ -221,20 +221,20 @@ Check:
|
|||||||
* CA:FALSE
|
* CA:FALSE
|
||||||
* OK
|
* OK
|
||||||
|
|
||||||
### Create a PKCS#12 bundle for the client
|
## Create a PKCS#12 bundle for the client
|
||||||
|
|
||||||
This is an easy(er) way to get all the necessary keys & certs to the client in one package.
|
This is an easy(er) way to get all the necessary keys & certs to the client in one package.
|
||||||
|
|
||||||
openssl pkcs12 -export -out client/pfx/test1.pfx -inkey client/private/test1.key.pem -in client/certs/test1.cert.pem -certfile intermediate/certs/chain.cert.pem
|
openssl pkcs12 -export -out client/pfx/test1.pfx -inkey client/private/test1.key.pem -in client/certs/test1.cert.pem -certfile intermediate/certs/chain.cert.pem
|
||||||
# Enter both the client key password, and a new password for the export; you'll need to give the latter to the client
|
# Enter both the client key password, and a new password for the export; you'll need to give the latter to the client
|
||||||
|
|
||||||
### Generate a certificate revocation list (CRL)
|
## Generate a certificate revocation list (CRL)
|
||||||
|
|
||||||
Initially empty. You can also do this for your root CA.
|
Initially empty. You can also do this for your root CA.
|
||||||
|
|
||||||
openssl ca -config openssl.cnf -gencrl -out intermediate/crl/intermediate.crl.pem
|
openssl ca -config openssl.cnf -gencrl -out intermediate/crl/intermediate.crl.pem
|
||||||
|
|
||||||
### Verify certificate revocation list
|
## Verify certificate revocation list
|
||||||
|
|
||||||
openssl crl -in intermediate/crl/intermediate.crl.pem -noout -text
|
openssl crl -in intermediate/crl/intermediate.crl.pem -noout -text
|
||||||
|
|
||||||
@@ -243,7 +243,7 @@ Check:
|
|||||||
* Expiration date (30 days in future)
|
* Expiration date (30 days in future)
|
||||||
* Signature algorithm (ecdsa-with-SHA256)
|
* Signature algorithm (ecdsa-with-SHA256)
|
||||||
|
|
||||||
### Revoke a certificate
|
## Revoke a certificate
|
||||||
|
|
||||||
Only do this if you need to. Find the certificate:
|
Only do this if you need to. Find the certificate:
|
||||||
|
|
||||||
|
|||||||
@@ -13,22 +13,22 @@ Searching for reasonably-priced options, I found the [Nitrokey HSM](https://shop
|
|||||||
|
|
||||||
Below are the steps to get the Nitrokey HSM to a working state where it can generate an EC key pair, and (self-)sign a cert with it. Hopefully many of these go away in the future, as support percolates into release versions and distribution packages.
|
Below are the steps to get the Nitrokey HSM to a working state where it can generate an EC key pair, and (self-)sign a cert with it. Hopefully many of these go away in the future, as support percolates into release versions and distribution packages.
|
||||||
|
|
||||||
### Hardware & setup
|
## Hardware & setup
|
||||||
|
|
||||||
These instructions were developed and tested on a Raspberry Pi. Base setup instructions are here. You’ll also need a Nitrokey HSM, obviously.
|
These instructions were developed and tested on a Raspberry Pi. Base setup instructions are here. You’ll also need a Nitrokey HSM, obviously.
|
||||||
|
|
||||||
### Install prerequisites
|
## Install prerequisites
|
||||||
|
|
||||||
sudo apt-get install pcscd libpcsclite-dev libssl-dev libreadline-dev autoconf automake build-essential docbook-xsl xsltproc libtool pkg-config git
|
sudo apt-get install pcscd libpcsclite-dev libssl-dev libreadline-dev autoconf automake build-essential docbook-xsl xsltproc libtool pkg-config git
|
||||||
|
|
||||||
### libccid
|
## libccid
|
||||||
|
|
||||||
You’ll need a [newer version of libccid](https://www.nitrokey.com/documentation/frequently-asked-questions#which-gnupg,-opensc-and-libccid-versions-are-required) than currently exists in Raspbian Jessie (1.4.22 > 1.4.18). You can download it for your platform here, or use the commands below for an RPi.
|
You’ll need a [newer version of libccid](https://www.nitrokey.com/documentation/frequently-asked-questions#which-gnupg,-opensc-and-libccid-versions-are-required) than currently exists in Raspbian Jessie (1.4.22 > 1.4.18). You can download it for your platform here, or use the commands below for an RPi.
|
||||||
|
|
||||||
wget http://http.us.debian.org/debian/pool/main/c/ccid/libccid_1.4.22-1_armhf.deb
|
wget http://http.us.debian.org/debian/pool/main/c/ccid/libccid_1.4.22-1_armhf.deb
|
||||||
sudo dpkg -i libccid_1.4.22-1_armhf.deb
|
sudo dpkg -i libccid_1.4.22-1_armhf.deb
|
||||||
|
|
||||||
### Install libp11
|
## Install libp11
|
||||||
|
|
||||||
engine\_pkcs11 requires >= 0.3.1. Raspbian Jessie has 0.2.8. Debian sid [has a package](https://packages.debian.org/sid/libp11-2), but you need the dev package as well, so you might as well build it.
|
engine\_pkcs11 requires >= 0.3.1. Raspbian Jessie has 0.2.8. Debian sid [has a package](https://packages.debian.org/sid/libp11-2), but you need the dev package as well, so you might as well build it.
|
||||||
|
|
||||||
@@ -40,7 +40,7 @@ engine\_pkcs11 requires >= 0.3.1. Raspbian Jessie has 0.2.8. Debian sid [has a p
|
|||||||
sudo make install
|
sudo make install
|
||||||
cd ..
|
cd ..
|
||||||
|
|
||||||
### Install engine\_pkcs11
|
## Install engine\_pkcs11
|
||||||
|
|
||||||
EC [requires engine\_pkcs11 >= 0.2.0](https://www.nitrokey.com/forum/viewtopic.php?t=1549). Raspbian Jessie has 0.1.8. Debian [sid also has a package](https://packages.debian.org/sid/libengine-pkcs11-openssl) that I haven’t tested.
|
EC [requires engine\_pkcs11 >= 0.2.0](https://www.nitrokey.com/forum/viewtopic.php?t=1549). Raspbian Jessie has 0.1.8. Debian [sid also has a package](https://packages.debian.org/sid/libengine-pkcs11-openssl) that I haven’t tested.
|
||||||
|
|
||||||
@@ -52,7 +52,7 @@ EC [requires engine\_pkcs11 >= 0.2.0](https://www.nitrokey.com/forum/viewtopic.p
|
|||||||
sudo make install
|
sudo make install
|
||||||
cd ..
|
cd ..
|
||||||
|
|
||||||
### Install OpenSC
|
## Install OpenSC
|
||||||
|
|
||||||
As of writing (2016/Mar/26), working support for the Nitrokey HSM [requires a build of OpenSC](https://www.nitrokey.com/documentation/frequently-asked-questions#which-gnupg,-opensc-and-libccid-versions-are-required) that hasn’t made it into a package yet (0.16.0). They’ve also screwed up their repository branching, so master is behind the release branch and won’t work.
|
As of writing (2016/Mar/26), working support for the Nitrokey HSM [requires a build of OpenSC](https://www.nitrokey.com/documentation/frequently-asked-questions#which-gnupg,-opensc-and-libccid-versions-are-required) that hasn’t made it into a package yet (0.16.0). They’ve also screwed up their repository branching, so master is behind the release branch and won’t work.
|
||||||
|
|
||||||
@@ -64,21 +64,21 @@ As of writing (2016/Mar/26), working support for the Nitrokey HSM [requires a bu
|
|||||||
sudo make install
|
sudo make install
|
||||||
cd ..
|
cd ..
|
||||||
|
|
||||||
### Misc
|
## Misc
|
||||||
|
|
||||||
sudo ldconfig
|
sudo ldconfig
|
||||||
|
|
||||||
### Initialize the device
|
## Initialize the device
|
||||||
|
|
||||||
/usr/local/bin/sc-hsm-tool --initialize
|
/usr/local/bin/sc-hsm-tool --initialize
|
||||||
|
|
||||||
If this tells you that it can’t find the device, you probably forgot to update libccid, and need to start over. You’ll need to set an SO PIN and PIN the first time. The SO PIN should be 16 characters, and the PIN 6. Both should be all digits. They can technically be hex, but some apps get confused if they see letters.
|
If this tells you that it can’t find the device, you probably forgot to update libccid, and need to start over. You’ll need to set an SO PIN and PIN the first time. The SO PIN should be 16 characters, and the PIN 6. Both should be all digits. They can technically be hex, but some apps get confused if they see letters.
|
||||||
|
|
||||||
### Generate a test EC key pair
|
## Generate a test EC key pair
|
||||||
|
|
||||||
/usr/local/bin/pkcs11-tool --module /usr/local/lib/opensc-pkcs11.so---login --keypairgen --key-type EC:prime256v1 --label test
|
/usr/local/bin/pkcs11-tool --module /usr/local/lib/opensc-pkcs11.so---login --keypairgen --key-type EC:prime256v1 --label test
|
||||||
|
|
||||||
### Generate a self-signed cert
|
## Generate a self-signed cert
|
||||||
|
|
||||||
openssl
|
openssl
|
||||||
OpenSSL> engine -t -pre SO_PATH:/usr/lib/arm-linux-gnueabihf/openssl-1.0.0/engines/libpkcs11.so -pre ID:pkcs11 -pre LIST_ADD:1 -pre LOAD -pre MODULE_PATH:/usr/local/lib/pkcs11/opensc-pkcs11.so dynamic
|
OpenSSL> engine -t -pre SO_PATH:/usr/lib/arm-linux-gnueabihf/openssl-1.0.0/engines/libpkcs11.so -pre ID:pkcs11 -pre LIST_ADD:1 -pre LOAD -pre MODULE_PATH:/usr/local/lib/pkcs11/opensc-pkcs11.so dynamic
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ There’s one material difference from the other instructions: the Nitrokey HSM
|
|||||||
|
|
||||||
XXXX is still our placeholder of choice.
|
XXXX is still our placeholder of choice.
|
||||||
|
|
||||||
### Create directory structure
|
## Create directory structure
|
||||||
|
|
||||||
mkdir ca
|
mkdir ca
|
||||||
cd ca
|
cd ca
|
||||||
@@ -23,7 +23,7 @@ XXXX is still our placeholder of choice.
|
|||||||
echo 1000 | tee {root,intermediate}/{serial,crlnumber}
|
echo 1000 | tee {root,intermediate}/{serial,crlnumber}
|
||||||
chmod 700 {client,server}/private
|
chmod 700 {client,server}/private
|
||||||
|
|
||||||
### Create openssl.cnf
|
## Create openssl.cnf
|
||||||
|
|
||||||
cat > openssl.cnf <<'END'
|
cat > openssl.cnf <<'END'
|
||||||
openssl_conf = openssl_init
|
openssl_conf = openssl_init
|
||||||
@@ -140,24 +140,24 @@ XXXX is still our placeholder of choice.
|
|||||||
init = 0
|
init = 0
|
||||||
END
|
END
|
||||||
|
|
||||||
### Tell future commands to use your new conf file
|
## Tell future commands to use your new conf file
|
||||||
|
|
||||||
export OPENSSL_CONF=openssl.cnf
|
export OPENSSL_CONF=openssl.cnf
|
||||||
|
|
||||||
### Create a root key
|
## Create a root key
|
||||||
|
|
||||||
Insert your root HSM.
|
Insert your root HSM.
|
||||||
|
|
||||||
/usr/local/bin/pkcs11-tool --module /usr/local/lib/opensc-pkcs11.so --login --keypairgen --key-type EC:prime256v1 --label root
|
/usr/local/bin/pkcs11-tool --module /usr/local/lib/opensc-pkcs11.so --login --keypairgen --key-type EC:prime256v1 --label root
|
||||||
# Enter PIN
|
# Enter PIN
|
||||||
|
|
||||||
### Create a self-signed root cert
|
## Create a self-signed root cert
|
||||||
|
|
||||||
openssl req -engine pkcs11 -keyform engine -key label_root -new -extensions ext_root -out root/certs/root.cert.pem -x509 -subj '/C=US/ST=California/O=XXXX/OU=XXXX Certificate Authority/CN=XXXX Root CA' -days 7300
|
openssl req -engine pkcs11 -keyform engine -key label_root -new -extensions ext_root -out root/certs/root.cert.pem -x509 -subj '/C=US/ST=California/O=XXXX/OU=XXXX Certificate Authority/CN=XXXX Root CA' -days 7300
|
||||||
# Enter PIN
|
# Enter PIN
|
||||||
chmod 444 root/certs/root.cert.pem
|
chmod 444 root/certs/root.cert.pem
|
||||||
|
|
||||||
### Verify root cert
|
## Verify root cert
|
||||||
|
|
||||||
openssl x509 -noout -text -in root/certs/root.cert.pem
|
openssl x509 -noout -text -in root/certs/root.cert.pem
|
||||||
|
|
||||||
@@ -168,25 +168,25 @@ Check:
|
|||||||
* Public key size (256 bit)
|
* Public key size (256 bit)
|
||||||
* CA:TRUE
|
* CA:TRUE
|
||||||
|
|
||||||
### Import root cert onto HSM
|
## Import root cert onto HSM
|
||||||
|
|
||||||
openssl x509 -in root/certs/root.cert.pem -out root/certs/root.cert.der -outform der
|
openssl x509 -in root/certs/root.cert.pem -out root/certs/root.cert.der -outform der
|
||||||
/usr/local/bin/pkcs11-tool --module /usr/local/lib/opensc-pkcs11.so --login --write-object root/certs/root.cert.der --type cert --label root
|
/usr/local/bin/pkcs11-tool --module /usr/local/lib/opensc-pkcs11.so --login --write-object root/certs/root.cert.der --type cert --label root
|
||||||
# Enter PIN
|
# Enter PIN
|
||||||
|
|
||||||
### Create an intermediate key
|
## Create an intermediate key
|
||||||
|
|
||||||
Insert your intermediate HSM
|
Insert your intermediate HSM
|
||||||
|
|
||||||
/usr/local/bin/pkcs11-tool --module /usr/local/lib/opensc-pkcs11.so --login --keypairgen --key-type EC:prime256v1 --label intermediate
|
/usr/local/bin/pkcs11-tool --module /usr/local/lib/opensc-pkcs11.so --login --keypairgen --key-type EC:prime256v1 --label intermediate
|
||||||
# Enter PIN
|
# Enter PIN
|
||||||
|
|
||||||
### Create an intermediate certificate signing request (CSR)
|
## Create an intermediate certificate signing request (CSR)
|
||||||
|
|
||||||
openssl req -engine pkcs11 -keyform engine -new -key label_intermediate -out intermediate/csr/intermediate.csr.pem -subj '/C=US/ST=California/O=XXXX/OU=XXXX Certificate Authority/CN=XXXX Intermediate'
|
openssl req -engine pkcs11 -keyform engine -new -key label_intermediate -out intermediate/csr/intermediate.csr.pem -subj '/C=US/ST=California/O=XXXX/OU=XXXX Certificate Authority/CN=XXXX Intermediate'
|
||||||
# Enter PIN
|
# Enter PIN
|
||||||
|
|
||||||
### Sign intermediate cert with root key
|
## Sign intermediate cert with root key
|
||||||
|
|
||||||
Insert your root HSM
|
Insert your root HSM
|
||||||
|
|
||||||
@@ -194,7 +194,7 @@ Insert your root HSM
|
|||||||
# Enter PIN
|
# Enter PIN
|
||||||
chmod 444 intermediate/certs/intermediate.cert.pem
|
chmod 444 intermediate/certs/intermediate.cert.pem
|
||||||
|
|
||||||
### Verify intermediate cert
|
## Verify intermediate cert
|
||||||
|
|
||||||
openssl x509 -noout -text -in intermediate/certs/intermediate.cert.pem
|
openssl x509 -noout -text -in intermediate/certs/intermediate.cert.pem
|
||||||
openssl verify -CAfile root/certs/root.cert.pem intermediate/certs/intermediate.cert.pem
|
openssl verify -CAfile root/certs/root.cert.pem intermediate/certs/intermediate.cert.pem
|
||||||
@@ -207,7 +207,7 @@ Check:
|
|||||||
* CA:TRUE
|
* CA:TRUE
|
||||||
* OK
|
* OK
|
||||||
|
|
||||||
### Import root & intermediate certs onto HSM
|
## Import root & intermediate certs onto HSM
|
||||||
|
|
||||||
Insert your intermediate HSM
|
Insert your intermediate HSM
|
||||||
|
|
||||||
@@ -217,18 +217,18 @@ Insert your intermediate HSM
|
|||||||
/usr/local/bin/pkcs11-tool --module /usr/local/lib/opensc-pkcs11.so --login --write-object intermediate/certs/intermediate.cert.der --type cert --label intermediate
|
/usr/local/bin/pkcs11-tool --module /usr/local/lib/opensc-pkcs11.so --login --write-object intermediate/certs/intermediate.cert.der --type cert --label intermediate
|
||||||
# Enter PIN
|
# Enter PIN
|
||||||
|
|
||||||
### Create a chain certificate file
|
## Create a chain certificate file
|
||||||
|
|
||||||
cat intermediate/certs/intermediate.cert.pem root/certs/root.cert.pem > intermediate/certs/chain.cert.pem
|
cat intermediate/certs/intermediate.cert.pem root/certs/root.cert.pem > intermediate/certs/chain.cert.pem
|
||||||
chmod 444 intermediate/certs/chain.cert.pem
|
chmod 444 intermediate/certs/chain.cert.pem
|
||||||
|
|
||||||
### CA setup done!
|
## CA setup done!
|
||||||
|
|
||||||
Take your root HSM, if you have a separate one, and lock it in a safe somewhere; you won’t need it for regular use.
|
Take your root HSM, if you have a separate one, and lock it in a safe somewhere; you won’t need it for regular use.
|
||||||
|
|
||||||
The following steps are examples of how to use your new CA.
|
The following steps are examples of how to use your new CA.
|
||||||
|
|
||||||
### Create a client key
|
## Create a client key
|
||||||
|
|
||||||
You can substitute “server” for “client” for a server cert.
|
You can substitute “server” for “client” for a server cert.
|
||||||
|
|
||||||
@@ -236,17 +236,17 @@ You can substitute “server” for “client” for a server cert.
|
|||||||
# Create client key password
|
# Create client key password
|
||||||
chmod 400 client/private/test1.key.pem
|
chmod 400 client/private/test1.key.pem
|
||||||
|
|
||||||
### Create a client certificate signing request (CSR)
|
## Create a client certificate signing request (CSR)
|
||||||
|
|
||||||
openssl req -new -key client/private/test1.key.pem -out client/csr/test1.csr.pem -subj '/C=US/ST=California/O=XXXX/OU=XXXX Test/CN=XXXX Test 1'
|
openssl req -new -key client/private/test1.key.pem -out client/csr/test1.csr.pem -subj '/C=US/ST=California/O=XXXX/OU=XXXX Test/CN=XXXX Test 1'
|
||||||
|
|
||||||
### Sign client cert with intermediate key
|
## Sign client cert with intermediate key
|
||||||
|
|
||||||
openssl ca -engine pkcs11 -keyform engine -extensions ext_client -notext -in client/csr/test1.csr.pem -out client/certs/test1.cert.pem
|
openssl ca -engine pkcs11 -keyform engine -extensions ext_client -notext -in client/csr/test1.csr.pem -out client/certs/test1.cert.pem
|
||||||
# Enter PIN
|
# Enter PIN
|
||||||
chmod 444 client/certs/test1.cert.pem
|
chmod 444 client/certs/test1.cert.pem
|
||||||
|
|
||||||
### Verify client cert
|
## Verify client cert
|
||||||
|
|
||||||
openssl x509 -noout -text -in client/certs/test1.cert.pem
|
openssl x509 -noout -text -in client/certs/test1.cert.pem
|
||||||
openssl verify -CAfile intermediate/certs/chain.cert.pem client/certs/test1.cert.pem
|
openssl verify -CAfile intermediate/certs/chain.cert.pem client/certs/test1.cert.pem
|
||||||
@@ -259,20 +259,20 @@ Check:
|
|||||||
* CA:FALSE
|
* CA:FALSE
|
||||||
* OK
|
* OK
|
||||||
|
|
||||||
### Create a PKCS#12 bundle for the client
|
## Create a PKCS#12 bundle for the client
|
||||||
|
|
||||||
This is an easy(er) way to get all the necessary keys & certs to the client in one package.
|
This is an easy(er) way to get all the necessary keys & certs to the client in one package.
|
||||||
|
|
||||||
openssl pkcs12 -export -out client/pfx/test1.pfx -inkey client/private/test1.key.pem -in client/certs/test1.cert.pem -certfile intermediate/certs/chain.cert.pem
|
openssl pkcs12 -export -out client/pfx/test1.pfx -inkey client/private/test1.key.pem -in client/certs/test1.cert.pem -certfile intermediate/certs/chain.cert.pem
|
||||||
# Enter both the client key password, and a new password for the export; you'll need to give the latter to the client
|
# Enter both the client key password, and a new password for the export; you'll need to give the latter to the client
|
||||||
|
|
||||||
### Generate a certificate revocation list (CRL)
|
## Generate a certificate revocation list (CRL)
|
||||||
|
|
||||||
Initially empty. You can also do this for your root CA (with its HSM inserted).
|
Initially empty. You can also do this for your root CA (with its HSM inserted).
|
||||||
|
|
||||||
openssl ca -engine pkcs11 -keyform engine -gencrl -out intermediate/crl/intermediate.crl.pem
|
openssl ca -engine pkcs11 -keyform engine -gencrl -out intermediate/crl/intermediate.crl.pem
|
||||||
|
|
||||||
### Verify certificate revocation list
|
## Verify certificate revocation list
|
||||||
|
|
||||||
openssl crl -in intermediate/crl/intermediate.crl.pem -noout -text
|
openssl crl -in intermediate/crl/intermediate.crl.pem -noout -text
|
||||||
|
|
||||||
@@ -281,7 +281,7 @@ Check:
|
|||||||
* Expiration date (30 days in future)
|
* Expiration date (30 days in future)
|
||||||
* Signature algorithm (ecdsa-with-SHA256)
|
* Signature algorithm (ecdsa-with-SHA256)
|
||||||
|
|
||||||
### Revoke a certificate
|
## Revoke a certificate
|
||||||
|
|
||||||
Only do this if you need to. Find the certificate:
|
Only do this if you need to. Find the certificate:
|
||||||
|
|
||||||
|
|||||||
@@ -5,16 +5,16 @@
|
|||||||
|
|
||||||
If you’re building system images, you’re going to do a lot of debootstrap, which is going to fetch a lot of packages. On a fast system, that’ll be the slowest part of the process. Here’s how to cache.
|
If you’re building system images, you’re going to do a lot of debootstrap, which is going to fetch a lot of packages. On a fast system, that’ll be the slowest part of the process. Here’s how to cache.
|
||||||
|
|
||||||
### Install apt-cacher-ng
|
## Install apt-cacher-ng
|
||||||
|
|
||||||
sudo apt-get install squid-deb-proxy
|
sudo apt-get install squid-deb-proxy
|
||||||
|
|
||||||
### Tell programs to use the proxy
|
## Tell programs to use the proxy
|
||||||
|
|
||||||
export http_proxy=http://127.0.0.1:8000
|
export http_proxy=http://127.0.0.1:8000
|
||||||
# Note that you'll need to re-export this before any use of debootstrap
|
# Note that you'll need to re-export this before any use of debootstrap
|
||||||
|
|
||||||
### Tell sudo to pass through http\_proxy
|
## Tell sudo to pass through http\_proxy
|
||||||
|
|
||||||
sudo visudo
|
sudo visudo
|
||||||
# Add the line after the env_reset line:
|
# Add the line after the env_reset line:
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ Your access point, however, does require support for this to work. It needs to:
|
|||||||
* Allow frames where the ethernet and WLAN source MAC addresses differ (like above, but a policy decision).
|
* Allow frames where the ethernet and WLAN source MAC addresses differ (like above, but a policy decision).
|
||||||
* Not assume that the WLAN MAC address is the only MAC at the other end of the link. This assumption is frequently used to reduce the effect of broadcast traffic in a WiFi environment by filtering. There may be settings like “Multicast optimization”, “Broadcast optimization”, or “DHCP optimization” that you need to turn off.
|
* Not assume that the WLAN MAC address is the only MAC at the other end of the link. This assumption is frequently used to reduce the effect of broadcast traffic in a WiFi environment by filtering. There may be settings like “Multicast optimization”, “Broadcast optimization”, or “DHCP optimization” that you need to turn off.
|
||||||
|
|
||||||
### Bridging
|
## Bridging
|
||||||
|
|
||||||
Linux supports bridging. There’s a bridge-utils package in Ubuntu with the tools you need:
|
Linux supports bridging. There’s a bridge-utils package in Ubuntu with the tools you need:
|
||||||
|
|
||||||
@@ -30,7 +30,7 @@ However, you can’t normally add a WiFi interface to a bridge:
|
|||||||
|
|
||||||
Googling this error produces a wide range of well-meaning yet completely unhelpful results.
|
Googling this error produces a wide range of well-meaning yet completely unhelpful results.
|
||||||
|
|
||||||
### Enable 4 address mode
|
## Enable 4 address mode
|
||||||
|
|
||||||
To be able to add a WiFi interface to a bridge, you have to put it into 4-address mode first:
|
To be able to add a WiFi interface to a bridge, you have to put it into 4-address mode first:
|
||||||
|
|
||||||
@@ -46,7 +46,7 @@ Now add the interface to a bridge:
|
|||||||
|
|
||||||
You should now be able to fetch an IP on br0 via DHCP. Unless, of course, you need wpa\_supplicant to work…
|
You should now be able to fetch an IP on br0 via DHCP. Unless, of course, you need wpa\_supplicant to work…
|
||||||
|
|
||||||
### wpa\_supplicant
|
## wpa\_supplicant
|
||||||
|
|
||||||
wpa\_supplicant needs to be bridge-aware to work with 4-address mode. Fortunately, it has a flag (-b) to set the bridge interface. Unfortunately, this flag is broken in 2.1, the version in Ubuntu Trusty. I verified that it works in wpa\_supplicant 2.5 built from source; I haven’t verified 2.4 from Xenial.
|
wpa\_supplicant needs to be bridge-aware to work with 4-address mode. Fortunately, it has a flag (-b) to set the bridge interface. Unfortunately, this flag is broken in 2.1, the version in Ubuntu Trusty. I verified that it works in wpa\_supplicant 2.5 built from source; I haven’t verified 2.4 from Xenial.
|
||||||
|
|
||||||
@@ -56,7 +56,7 @@ A wpa\_supplicant commandline looks something like:
|
|||||||
|
|
||||||
With that working, the interface should get to wpa\_state=COMPLETED, and br0 should work normally. Remember that wlan0 will still be unusable directly.
|
With that working, the interface should get to wpa\_state=COMPLETED, and br0 should work normally. Remember that wlan0 will still be unusable directly.
|
||||||
|
|
||||||
### Ordering
|
## Ordering
|
||||||
|
|
||||||
Bringing up these interfaces is tricky; the ordering is annoying.
|
Bringing up these interfaces is tricky; the ordering is annoying.
|
||||||
|
|
||||||
@@ -64,7 +64,7 @@ Bringing up these interfaces is tricky; the ordering is annoying.
|
|||||||
* br0 must exist before you can start wpa\_supplicant
|
* br0 must exist before you can start wpa\_supplicant
|
||||||
* wpa\_supplicant must be running before you can get an IP address on br0
|
* wpa\_supplicant must be running before you can get an IP address on br0
|
||||||
|
|
||||||
### Putting it together
|
## Putting it together
|
||||||
|
|
||||||
Because of the ordering issues, it’s easier to treat this all as one interface that has to come up together. Here’s an example interface stanza that does this:
|
Because of the ordering issues, it’s easier to treat this all as one interface that has to come up together. Here’s an example interface stanza that does this:
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user