switching over to https
- 3 minutes read - 481 wordsOne of the things I’ve been meaning to do forever is switch things over to https. By “things”, I mean the set of websites I run for some family and friends. I tried it out with my personal website first, then flipped over the rest.
implementation notes
- I used the letsencrypt start guide to generate the certificates.
- Modified the nginx config to: a. serve ssl/https traffic on port 443 for the given domain with the proper https certificates/etc. b. forward non-ssl/http traffic on port 80 to port 443 for the given domain
verification
It turns out that the nginx configuration files are a little bit error prone. This probably means that I am doing something wrong, like not using some configuration management tool like puppet or ansible or whatever. But for something as small scale as my site, it doesn’t really meet the cost-benefit threshold for learning a new tool/language. I also even considered spinning up a simple one-off configuration generator that I’d need to figure out how to override and extend as needed.
My first step was to write a simple requests call that can get the response given a scheme and hostname:
def check_scheme_host(scheme, hostname):
url = "{scheme}://{hostname}/".format(
hostname=hostname,
scheme=scheme,
)
try:
resp = requests.get(url, allow_redirects=False)
except Exception:
return None
return resp
Note that our check disallows redirects, because otherwise requests would just helpfully follow the 301s. Since the 301s are part of what we’re trying to verify, we don’t want to follow them.
Given that that function, we can define our expectations for a given check. In particular, we can define a function that expects a certain response code for a given hostname and scheme:
def expect_check(expected_response, hostname, scheme):
actual_response = check_scheme_host(scheme, hostname)
if actual_response != None and actual_response.status_code == expected_response:
return hostname + " passed " + scheme + " check!"
else:
return hostname + " failed " + scheme + " check!"
Finally, we can check a given hostname:
def check_host(hostname):
print expect_check(301, hostname, "http")
print expect_check(200, hostname, "https")
This would let us make calls like
check_host("traviscj.com")
which would print out something like
traviscj.com passed http check!
traviscj.com passed https check!
With that in place, we need some definition of which hosts we want to check. Obviously, we could just define it in the python source, but it’d be nice to make it a bit more reusable. So let’s define a simple JSON file that includes the hostnames that I want to ensure work correctly. Here’s a sample of a few of them:
[
{
"host": "bovineherdhealth.com"
},
{
"host": "priceofth.at"
},
{
"host": "traviscj.com"
}
]
and a tiny bit of file loading logic:
def from_file(hosting_check_filename):
with open(hosting_check_filename) as hosting_check_file:
hosting_check = json.load(hosting_check_file)
for entry in hosting_check:
check_host(entry['host'])
and finally, a tiny final bit wiring:
def main():
from_file('/Users/traviscj/hosting-check/hosting_check.json')
if __name__ == "__main__":
main()
And now we have a way to test all the host forwarders.