8 ms·
still no solutions for IoT devices serving webpages like routers , nas, ip cameras, etc
by greggman 9y ago
still no solutions for IoT devices serving webpages like routers , nas, ip cameras, etc
- prophesi 9y agoI'm hoping in the future it'll be easier (in a secure fashion) to implement self-signed certs for those sorts of things that only have to serve pages on a local network.
- emilecantin 9y agoWe had a lengthy discussion today in the SignalK project (http://signalk.org/ http://signalk.org/) about exactly that. The best approach I've seen so far is the way Plex has done it: https://en.wikipedia.org/wiki/Plex_(software)#SSL https://en.wikipedia.org/wiki/Plex_(software)#SSL
- prophesi 9y agoWow, that's an ingenious solution! It's such a shame that this requires jumping through so many hoops (and becoming a Registration Authority... Not sure how difficult or pricy that would be). And I never heard of Signal K. That is an awesome project, and definitely could benefit from end-to-end encryption for transporting marine data.
- emilecantin 9y agoYeah, becoming a CA is kind of a PITA. I think a "Sub-domain CA" would be a kind of happy middle ground, as it wouldn't need to be trusted as much. Also, the Plex approach requires some DNS trickery, which works well when you're online, but on a boat in the middle of an ocean, it might be harder... We need a way to secure local-only communications, with local-only names (like .local). While we're at it, mDNS support in browsers would be nice, too.
- lmm 9y agoThe whole idea of HTTPS is that a given domain name has a single, globally-consistent meaning, that a user can trust that a given name will be the same thing anywhere. I don't think .local should be able to override that, that would be a large-scale phishing incident waiting to happen.
- lmm 9y agoSetting up an internal CA really isn't a lot of hoops - any nontrivial tech company does it, anyone running a Mumble or OpenVPN server does it. (I don't know about the requirements for having one signed by the public infrastructure though)
- dalore 9y agoYou still need to distribute the CA certs so they are trusted by various browsers. Which isn't a solution for the public.
- lmm 9y agoYou can have the end webserver serve the intermediate chain, no?
- dalore 9y agoIf you create your own CA it's not trusted by your browser. Intermediate chains have nothing to do with it because at the end of the chain is no trust.
- lmm 9y agoPlex became an intermediate CA, not a root CA, right? Or did I misunderstand?
- dalore 9y agoSmall misunderstanding. The browsers have a list of CA's they trust. Let's call them the root CAs. You normally won't get a http cert signed by a root CA, it's normally done by an intermediate CA. Now your browser doesn't that, but it's been signed by a root CA so your browser eventually trusts it. You get your server to also serve the intermediate CA certs to save a round trip for requesting it. But in the end, because it's the chain of trust, your browser trusts it because it's eventually signed by a trusted root CA. Now if you create your own CA you will need to be installed in the users browsers to trust. Even if you put the intermediate certificates as your browser can't establish a link of trust.
- tzs 9y agoI've never found a good, single document that covers self-signed certificates well. Googling for guidance results in a lot of different ways to do it, and if you don't find one that does exactly what you want, trying to combine that one with a different one that does the things missing from the first might not work because they are using different approaches. I did manage to glean enough to make a pair of simple scripts that seemed to work for my needs, but have no idea if they are actually right, or if putting together things from different guides messed things up. Here's the script I use for my root certificate (makeroot.sh): #!/bin/bash NAME=${1:?Must specify name for root} CN=${CN:-My Little Certificate Authority} O=${O:-My Home Network} C=${C:-US} DAYS=${DAYS:-365} PW=${PW:--aes256} SUBJ="/CN=$CN/O=$O/C=$C" openssl genrsa $PW -out $NAME.key 2048 openssl req -x509 -new -subj "$SUBJ" -nodes -key $NAME.key -sha256 -days $DAYS -out $NAME.pem So suppose I'm setting up a private certificate authority for my iot devices. I would do: $ ./makeroot.sh iot That will make iot.key and iot.pem. To make a certificate signed with the iot certificate I use this script (makecert.sh): #!/bin/bash NAME=${1:?Must specify name for cert} ROOT=${2:?Must specify name for root} CA="-CA $ROOT.pem -CAkey $ROOT.key -CAcreateserial" O=${O:-My Home Network} C=${C:-US} DAYS=${DAYS:-365} SUBJ="/CN=$NAME/O=$O/C=$C" openssl genrsa -out $NAME.key 2048 openssl req -new -key $NAME.key -subj "$SUBJ" -out $NAME.csr openssl x509 -req -in $NAME.csr $CA -out $NAME.crt -days $DAYS -sha256 rm $NAME.csr E.g., to make a key for an iot doorbell: $ ./makecert.sh doorbell iot That makes doorbell.crt and doorbell.key. That worked well until the need arose to make an SNI certificate. I had expected that it would just be a matter of slightly tweaking makecert.sh, add a few more arguments. But all I could find in the way of examples took a different approach, where most of the information is passed in a config file, and some of the guides I read indicated that you cannot pass the names on the command line to openssl when doing SNI. Anyway, this is the script I came up with (makesni.sh): #!/bin/bash function makeconf { CN=$1 DIR='$dir' shift cat > tmp.conf <<HERE [ req ] distinguished_name = dn req_extensions = req_ext unique_subject = no prompt = no [ ca ] default_ca = tzs_ca [ tzs_ca ] dir = ca-files private_key = $DIR/iot.key certificate = $DIR/iot.pem new_certs_dir = $DIR database = $DIR/index.txt # database index file. unique_subject = no default_md = sha256 # use public key default MD serial = $DIR/iot.srl # The current serial number email_in_dn = tzs@mouse-potato.com default_days = 365 [ dn ] CN = $CN O = My Home Network C = US [ policy_anything ] countryName = optional stateOrProvinceName = optional localityName = optional organizationName = optional organizationalUnitName = optional commonName = supplied emailAddress = optional [req_ext] HERE if [ -n "$1" ] then cat >> tmp.conf <<HERE subjectAltName = @alts [ alts ] DNS.1 = $1 HERE shift fi POS=2 while [ -n "$1" ] do echo "DNS.$POS = $1" >> tmp.conf shift POS=$((POS + 1)) done } NAME=${1:?Must specify name for cert} makeconf $* openssl genrsa -out out/$NAME.key 2048 openssl req -new -key out/$NAME.key -config tmp.conf -out out/$NAME.csr openssl ca -policy policy_anything -out out/$NAME.crt -config tmp.conf -extensions req_ext -infiles out/$NAME.csr rm out/$NAME.csr tmp.conf This assumes a directory, ca_files, that contains iot.key and iot.pem, and also an empty file named index.txt. Also it assumes in out directory. To make an SNI certificate for a device that has three hosts, named fridge, freezer, and icemaker: $ ./makesni.sh fridge freezer icemaker That will make fridge.crt and fridge.key in the out directory, and that will have fridge as the CN and freezer and icemaker as subject alternate names. OK, so now I can put doorbell.crt and doorbell.key on the doorbell device, and fridge.crt and fridge.key on the device that has the fridge, freezer, and icemaker sites, and all is well, right? Well...I also need to give my browsers iot.pem so they will recognize those other certificates. I'd also like curl and Perl and Python to recognize them, so that I can write scripts that do fancy iot things. I didn't find any good guide to installing the CA certificate. From a bunch of Googling I came up with: • On Debian Linux, copy iot.pem to /usr/local/share/ca-certificates, and change the extension to .crt. Run update-ca-certificates. That should make it available to Perl, Python, and curl. For Chrome and Firefox, find their certificate management dialogs and use them to add the certificate. • On OS X, double-click iot.pem. That should open Keychain Access. Let it import the certificate. Set it to be trusted for SSL. That will make it work in Chrome and Safari. For Firefox, same as Linux. For Perl, do one of: 1. Set environment variable PERL_LWP_SSL_CA_PATH or HTTPS_CA_DIR to point to a directory containing iot.pem, or 2. Set the environment variable PERL_LWP_SSL_CA_FILE of HTTPS_CA_FILE to point to iot.pem, or The first requires that the directory contain symbolic links of the form hash.N where hash is a hash of the certificate and N is a sequence number. You need two of these, because there apparently is an old hash and a new hash. 'openssl x509 -subject_hash -noout -in iot.pem' to get the new hash, and 'openssl x509 -subject_hash_old -noout -in iot.pem' to get the old hash. Or just go to the cert directory and run 'c_rehash .' and 'c_rehash -old .' and those will make all the symlinks for you. For Python3, similar to Perl but with SSL_CERT_DIR and SSL_CERT_FILE as the environment variable. Same hash symlinks as Perl (although I think you only need the new hash). For curl, "--cacert iot.pem" or "--capath <dir>" where <dir> is a directory with the certificate. Same symlink considerations as Python3. Or set CURL_CA_BUNDLE env variable to point to a bundle that contains iot.pem. A bundle is just a bunch of certificate fills concatenated. • Windows, I have no idea.
- jacquesm 9y agoThose should never be exposed beyond your local network. Any access to them should be vetted and encrypted by something more heavyweight before it hits the WAN.
- greggman 9y agoThe problem is browsers are deprecating feature if not https so those devices can’t use the features without https but there is no solution for them to use https
- dalore 9y agoWell they shouldn't be accessed via http if you're not in your own network. So you can just create a proxy that has a https cert and proxies to http. Let's you add authentication, log access, etc.
- zanny 9y agoYou can probably automate this actually. There are several domains you can subdomain on afraid (or better yet the router manufacturer / nas manufacturer / camera company etc should be providing a subdomained address per device) and then get issued a cert for (letsencrypt uses the public suffix list to remove rate limiting from some of the afraid domains mentioned before, and any company interested should get their catchall domain added to that list). Then it just comes down to doing the same redirects / hsts policy for insecure connections, but I believe they would have to be done at the root domain level, again going back to manufacturers providing them. The letsencrypt part itself is the easy part, the hard bit is getting the domain name to register under. All the good open source router firmware today already supports Dynamic DNS. All that being said, every Internet of Things device made is a security nightmare and none of the manufacturers give a damn, so they will never see a reasonable expectation of security or do anything like this. They cannot even produce a common OS amongst themselves to keep their firmware up to date and free of security vulnerabilities.