Use words rather than numerals for values <10
http://www.gatehousenewsroom.com/2015/08/12/ap-style-numbers-age-score-year-ratios/
This commit is contained in:
parent
0fc958b688
commit
190b317fe7
33 changed files with 83 additions and 83 deletions
|
@ -5,13 +5,13 @@ subtitle: Potential account hijack via password reset form
|
||||||
tags: [security]
|
tags: [security]
|
||||||
---
|
---
|
||||||
|
|
||||||
Yesterday, an email was sent to `django-announce`, informing of an upcoming security update, labelled "high" severity. Previous notifications like this have been 1 week before the actual disclosure; This email, just 12 hours. The updates were scheduled to be released 12:00 UTC the next day (today). Already, not the best thing to be reading just 1 week before Christmas, and 1 day before the company production freeze.
|
Yesterday, an email was sent to `django-announce`, informing of an upcoming security update, labelled "high" severity. Previous notifications like this have been one week before the actual disclosure; This email, just 12 hours. The updates were scheduled to be released 12:00 UTC the next day (today). Already, not the best thing to be reading just one week before Christmas, and one day before the company production freeze.
|
||||||
|
|
||||||
{{< resource src="initial-announcement-email.png" >}}
|
{{< resource src="initial-announcement-email.png" >}}
|
||||||
Email announcing the upcoming security release.
|
Email announcing the upcoming security release.
|
||||||
{{< /resource >}}
|
{{< /resource >}}
|
||||||
|
|
||||||
This morning, at 09:23 UTC, said updates were [released](https://www.djangoproject.com/weblog/2019/dec/18/security-releases/), and an email hit my inbox, almost 3 hours early. I can only imagine what seeing that notification did to my heart rate.
|
This morning, at 09:23 UTC, said updates were [released](https://www.djangoproject.com/weblog/2019/dec/18/security-releases/), and an email hit my inbox, almost three hours early. I can only imagine what seeing that notification did to my heart rate.
|
||||||
|
|
||||||
{{< resource src="release-email.png" >}}
|
{{< resource src="release-email.png" >}}
|
||||||
Email announcing the release
|
Email announcing the release
|
||||||
|
@ -23,7 +23,7 @@ It's around this time I realised today would be _interesting_.
|
||||||
|
|
||||||
The vulnerability itself is a side-effect of how case-insensitive SQL queries work in many locale-aware database engines, and how this relates to email sending. The patches were applied to `django.contrib.auth.forms.PasswordResetForm`. Libraries which use this form directly, with little to no modification, such as `django-rest-auth`, shouldn't require any additional patches, besides bumping the Django version.
|
The vulnerability itself is a side-effect of how case-insensitive SQL queries work in many locale-aware database engines, and how this relates to email sending. The patches were applied to `django.contrib.auth.forms.PasswordResetForm`. Libraries which use this form directly, with little to no modification, such as `django-rest-auth`, shouldn't require any additional patches, besides bumping the Django version.
|
||||||
|
|
||||||
The exact fix for CVE-2019-19844 came in 2 parts: Fixing unicode comparison, and not trusting user input.
|
The exact fix for CVE-2019-19844 came in two parts: Fixing unicode comparison, and not trusting user input.
|
||||||
|
|
||||||
If your project, or a package you maintain, handles password reset in a custom way, however small, as `django-allauth` [did](https://github.com/pennersr/django-allauth/commit/9ec5a5456a59781771e1c3a0df3d555a0089accd), or overrides specific parts of `PasswordResetForm`, keep reading! Alternatively, if you're like me and find security vulnerabilities or weird unicode issues interesting, you should keep reading too.
|
If your project, or a package you maintain, handles password reset in a custom way, however small, as `django-allauth` [did](https://github.com/pennersr/django-allauth/commit/9ec5a5456a59781771e1c3a0df3d555a0089accd), or overrides specific parts of `PasswordResetForm`, keep reading! Alternatively, if you're like me and find security vulnerabilities or weird unicode issues interesting, you should keep reading too.
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ Whilst I could go quite in depth about unicode, why it's great, why it's terribl
|
||||||
- [Why Do Flag Emoji Count As Two Characters?](https://www.youtube.com/watch?v=sTzp76JXsoY)
|
- [Why Do Flag Emoji Count As Two Characters?](https://www.youtube.com/watch?v=sTzp76JXsoY)
|
||||||
- [⚫ How The Black Point Message Crashes Android Apps](https://www.youtube.com/watch?v=jC4NNUYIIdM)
|
- [⚫ How The Black Point Message Crashes Android Apps](https://www.youtube.com/watch?v=jC4NNUYIIdM)
|
||||||
|
|
||||||
The issue with this relies on collisions, where 2 characters can have the same operation done to them, such as changing their case, and produce the same output.
|
The issue with this relies on collisions, where two characters can have the same operation done to them, such as changing their case, and produce the same output.
|
||||||
|
|
||||||
A good example of this is the "ß" character in German. The german alphabet has an extra character when compared to the standard english alphabet, "ß", which sounds _almost_ identical to a "ss". As a human, watching a computer interact with this can lead to some confusing results:
|
A good example of this is the "ß" character in German. The german alphabet has an extra character when compared to the standard english alphabet, "ß", which sounds _almost_ identical to a "ss". As a human, watching a computer interact with this can lead to some confusing results:
|
||||||
|
|
||||||
|
@ -89,7 +89,7 @@ Once Django pulls users out of the database, and validates they have usable pass
|
||||||
|
|
||||||
Email addresses, and domain names for that matter, are widely accepted as being case insensitive. ME@GOOGLE.COM and me@google.com will probably end up in the same place, just as browsing to `GOOGLE.COM` will probably lead you to that ~~data collector~~ search engine you know and love.
|
Email addresses, and domain names for that matter, are widely accepted as being case insensitive. ME@GOOGLE.COM and me@google.com will probably end up in the same place, just as browsing to `GOOGLE.COM` will probably lead you to that ~~data collector~~ search engine you know and love.
|
||||||
|
|
||||||
The issue here lies in the fact that the 2 don't work in exactly the same way. PostgreSQL, and many other locale-aware storages consider the locale when comparing case-insensitive. DNS on the other hand, converts domains to [punycode](https://en.wikipedia.org/wiki/Punycode) before resolving, at which point the character becomes 'just another character'.
|
The issue here lies in the fact that the two don't work in exactly the same way. PostgreSQL, and many other locale-aware storages consider the locale when comparing case-insensitive. DNS on the other hand, converts domains to [punycode](https://en.wikipedia.org/wiki/Punycode) before resolving, at which point the character becomes 'just another character'.
|
||||||
|
|
||||||
For example, the GitHub attack used the Turkish dotless i "ı". "GıtHub" isn't the same as "GitHub" to us, nor is it to DNS, where it becomes the punycode `gthub-2ub`, but as far as case-insensitive locale-correctness is concerned, they're the same, or at least the same enough.
|
For example, the GitHub attack used the Turkish dotless i "ı". "GıtHub" isn't the same as "GitHub" to us, nor is it to DNS, where it becomes the punycode `gthub-2ub`, but as far as case-insensitive locale-correctness is concerned, they're the same, or at least the same enough.
|
||||||
|
|
||||||
|
@ -97,7 +97,7 @@ Now this isn't a bash on PostgreSQL, what they're doing is definitely correct, a
|
||||||
|
|
||||||
## _"So how does all this relate to CVE-2019-19844?"_
|
## _"So how does all this relate to CVE-2019-19844?"_
|
||||||
|
|
||||||
Back on topic, CVE-2019-19844. As I said, the patch to Django was in 2 parts: Fixing unicode comparisons, and fixing user input.
|
Back on topic, CVE-2019-19844. As I said, the patch to Django was in two parts: Fixing unicode comparisons, and fixing user input.
|
||||||
|
|
||||||
> 1. After retrieving a list of potentially-matching accounts from the database, Django's password reset functionality now also checks the email address for equivalence in Python, using the recommended identifier-comparison process from Unicode Technical Report 36, section 2.11.2(B)(2).
|
> 1. After retrieving a list of potentially-matching accounts from the database, Django's password reset functionality now also checks the email address for equivalence in Python, using the recommended identifier-comparison process from Unicode Technical Report 36, section 2.11.2(B)(2).
|
||||||
> 2. When generating password-reset emails, Django now sends to the email address retrieved from the database, rather than the email address submitted in the password-reset request form.
|
> 2. When generating password-reset emails, Django now sends to the email address retrieved from the database, rather than the email address submitted in the password-reset request form.
|
||||||
|
@ -114,7 +114,7 @@ Once users have been retrieved from the database using `PasswordResetForm.get_us
|
||||||
|
|
||||||
#### Non-obvious patch
|
#### Non-obvious patch
|
||||||
|
|
||||||
The exact change to this isn't obvious. Take the below 2 code examples. These are 2 snippets of the same method on `PasswordResetForm`, taken from Django's `master` branch. 1 is vulnerable to CVE-2019-19844, the other is not.
|
The exact change to this isn't obvious. Take the below two code examples. These are two snippets of the same method on `PasswordResetForm`, taken from Django's `master` branch. one is vulnerable to CVE-2019-19844, the other is not.
|
||||||
|
|
||||||
This method is vulnerable:
|
This method is vulnerable:
|
||||||
|
|
||||||
|
@ -194,7 +194,7 @@ def save(self, domain_override=None,
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
Spot the difference yet? It's just 5 characters.
|
Spot the difference yet? It's just five characters.
|
||||||
|
|
||||||
The issue is which email address is passed into `self.send_mail`. In the vulnerable example, `email` is passed, which is pulled from `self.cleaned_data["email"]`, which is the user-provided address. Whereas the fixed example passes `user_email`, which is pulled form `getattr(user, email_field_name)`, and therefore from the database address.
|
The issue is which email address is passed into `self.send_mail`. In the vulnerable example, `email` is passed, which is pulled from `self.cleaned_data["email"]`, which is the user-provided address. Whereas the fixed example passes `user_email`, which is pulled form `getattr(user, email_field_name)`, and therefore from the database address.
|
||||||
|
|
||||||
|
@ -218,7 +218,7 @@ If you are doing this, add a test case to make sure it works, and doesn't accide
|
||||||
|
|
||||||
The biggest take away from this is to keep things up-to-date. If you take nothing else away, let it be that! Packages are updated for far more important reasons than simply new features or a slight performance improvement.
|
The biggest take away from this is to keep things up-to-date. If you take nothing else away, let it be that! Packages are updated for far more important reasons than simply new features or a slight performance improvement.
|
||||||
|
|
||||||
If you're reading this, and have projects on versions of Django older than 3.0.1, 2.2.9, and 1.11.27, please go and fix them. Today I audited, patched, reviewed and deployed over 20 projects, in 1 day!
|
If you're reading this, and have projects on versions of Django older than 3.0.1, 2.2.9, and 1.11.27, please go and fix them. Today I audited, patched, reviewed and deployed over 20 projects, in one day!
|
||||||
|
|
||||||
When accepting user input, use it directly for as little as possible, and where you do have to use it, make sure it's valid and sanitary.
|
When accepting user input, use it directly for as little as possible, and where you do have to use it, make sure it's valid and sanitary.
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ django.core.exceptions.ImproperlyConfigured: Error loading psycopg2 module: /hom
|
||||||
|
|
||||||
As this was a work machine, I didn't have the time to research into the correct solution. I knew this was something to do with updates, because that's all that had changed between the last time it worked and now. But I had a feeling rolling back updates to a given date, especially on arch, would be fairly painful. Much to my surprise, it was super simple!
|
As this was a work machine, I didn't have the time to research into the correct solution. I knew this was something to do with updates, because that's all that had changed between the last time it worked and now. But I had a feeling rolling back updates to a given date, especially on arch, would be fairly painful. Much to my surprise, it was super simple!
|
||||||
|
|
||||||
After frantically googling, so my boss didn't notice my downtime, I found [this](https://www.ostechnix.com/downgrade-packages-specific-date-arch-linux/) article, which solved my needs completely. A simple config edit, and 1 command, and I was back to working.
|
After frantically googling, so my boss didn't notice my downtime, I found [this](https://www.ostechnix.com/downgrade-packages-specific-date-arch-linux/) article, which solved my needs completely. A simple config edit, and one command, and I was back to working.
|
||||||
|
|
||||||
## Doing the rollback
|
## Doing the rollback
|
||||||
The way this solution works is by rather than using the current state of the package repos, we use an archive from a specific date.
|
The way this solution works is by rather than using the current state of the package repos, we use an archive from a specific date.
|
||||||
|
@ -47,7 +47,7 @@ Depending on what packages have been downgraded, you may have to reboot to apply
|
||||||
To revert, just restore the backup of the pacman mirrorlist, and re-run the above pacman command.
|
To revert, just restore the backup of the pacman mirrorlist, and re-run the above pacman command.
|
||||||
|
|
||||||
## Outdated Packages
|
## Outdated Packages
|
||||||
Generally, having out of date packages on your system is a bad idea. Not only for security reasons, but stability and compatibility. [The article](https://www.ostechnix.com/downgrade-packages-specific-date-arch-linux/) goes through a couple more too.
|
Generally, having out of date packages on your system is a bad idea. Not only for security reasons, but stability and compatibility. [The article](https://www.ostechnix.com/downgrade-packages-specific-date-arch-linux/) goes through a couple more too.
|
||||||
|
|
||||||
## Actually solving my issue
|
## Actually solving my issue
|
||||||
A few days later, After [posting this article on twitter](https://twitter.com/RealOrangeOne/status/907591524644466688), I had a discussion with [@MortenLinderud](https://twitter.com/MortenLinderud) about the issue, who [pointed out](https://twitter.com/MortenLinderud/status/908262748718596096) that the library had already been fixed. So after updating `psycopg2`, my issue went away!
|
A few days later, After [posting this article on twitter](https://twitter.com/RealOrangeOne/status/907591524644466688), I had a discussion with [@MortenLinderud](https://twitter.com/MortenLinderud) about the issue, who [pointed out](https://twitter.com/MortenLinderud/status/908262748718596096) that the library had already been fixed. So after updating `psycopg2`, my issue went away!
|
||||||
|
|
|
@ -4,9 +4,9 @@ date: 2019-04-01
|
||||||
tags: [programming]
|
tags: [programming]
|
||||||
---
|
---
|
||||||
|
|
||||||
April marks the release of Django 2.2, the latest LTS version of the popular Python web framework. Django 2.2 marks almost 2 years of development since the last LTS release, 1.11 in April 2017, and brings with it some very large improvements and changes which naturally come with a major version bump.
|
April marks the release of Django 2.2, the latest LTS version of the popular Python web framework. Django 2.2 marks almost two years of development since the last LTS release, 1.11 in April 2017, and brings with it some very large improvements and changes which naturally come with a major version bump.
|
||||||
|
|
||||||
Django historically works off the LTS pattern of software releasing, providing 2 channels. LTS versions are maintained far longer than regular versions, and receive regular bug fixes and security patches in line with the main release channel.
|
Django historically works off the LTS pattern of software releasing, providing two channels. LTS versions are maintained far longer than regular versions, and receive regular bug fixes and security patches in line with the main release channel.
|
||||||
|
|
||||||
![Django update cycle](https://static.djangoproject.com/img/release-roadmap.png)
|
![Django update cycle](https://static.djangoproject.com/img/release-roadmap.png)
|
||||||
|
|
||||||
|
@ -166,7 +166,7 @@ This can then be used by JavaScript directly by getting the tag by ID. If you st
|
||||||
|
|
||||||
## Constraints
|
## Constraints
|
||||||
|
|
||||||
The new constraints API in Django 2.2 allows for far greater control of database-level validation on model fields than previously available in field validators, because they're applied at the model level, rather than the field level. Django 2.2 comes with 2 built-in constraints: `UniqueConstraint` and `CheckConstraint`. Both constraints are executed at the database level (as additional queries rather than column-level constraints), which whilst making them faster when doing complex relationship-level validation, also increases the number of queries executed when modifying a model instance.
|
The new constraints API in Django 2.2 allows for far greater control of database-level validation on model fields than previously available in field validators, because they're applied at the model level, rather than the field level. Django 2.2 comes with two built-in constraints: `UniqueConstraint` and `CheckConstraint`. Both constraints are executed at the database level (as additional queries rather than column-level constraints), which whilst making them faster when doing complex relationship-level validation, also increases the number of queries executed when modifying a model instance.
|
||||||
|
|
||||||
`UniqueConstranint` creates a unique constraint with any number of fields, in much the same way `unique_together` worked. `UniqueConstraint` also provides an additional `condition` argument, which specifies additional `Q` objects which must also apply. For example, `UniqueConstraint(fields=['user'], condition=Q(status='DRAFT')` ensures that each user only has one draft.
|
`UniqueConstranint` creates a unique constraint with any number of fields, in much the same way `unique_together` worked. `UniqueConstraint` also provides an additional `condition` argument, which specifies additional `Q` objects which must also apply. For example, `UniqueConstraint(fields=['user'], condition=Q(status='DRAFT')` ensures that each user only has one draft.
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ One thing I see a lot is people recommending how they do it, or stating how some
|
||||||
|
|
||||||
## Techniques
|
## Techniques
|
||||||
|
|
||||||
I don't think there is 1 right answer which is applicable for everyone in all cases. There's always a trade off between complexity, security, and features. Here's the most commonly suggested one:
|
I don't think there is one right answer which is applicable for everyone in all cases. There's always a trade off between complexity, security, and features. Here's the most commonly suggested one:
|
||||||
|
|
||||||
### Don't
|
### Don't
|
||||||
|
|
||||||
|
@ -77,7 +77,7 @@ Another potential downside, however niche, is that public IPs of residential loc
|
||||||
|
|
||||||
### VPN only
|
### VPN only
|
||||||
|
|
||||||
In short, a VPN allows you to bridge 2 isolated networks together. You can use a VPN to access the devices behind your home firewall, from anywhere with an internet connection.
|
In short, a VPN allows you to bridge two isolated networks together. You can use a VPN to access the devices behind your home firewall, from anywhere with an internet connection.
|
||||||
|
|
||||||
This method works in a very similar way to the Port forward technique above, however rather than opening the ports needed for web traffic, you open up the ports needed for a VPN server, and tunnel your traffic through that. This removes the ability for just anyone to access your applications, and requires you to install client software on any devices which require access, but yields a very secure and versatile connection model. You will however still need to manage dynamic DNS if your house doesn't have a static IP.
|
This method works in a very similar way to the Port forward technique above, however rather than opening the ports needed for web traffic, you open up the ports needed for a VPN server, and tunnel your traffic through that. This removes the ability for just anyone to access your applications, and requires you to install client software on any devices which require access, but yields a very secure and versatile connection model. You will however still need to manage dynamic DNS if your house doesn't have a static IP.
|
||||||
|
|
||||||
|
@ -118,7 +118,7 @@ VPN servers are incredibly lightweight, and will easily run on a Raspberry Pi. [
|
||||||
|
|
||||||
An alternative to opening ports and directing users straight to your home router, you can use a VPN as a gateway. This allows you to forward ports to inside your home, but without actually port forwarding. No modifications to your home network are necessary. Users are pointed towards a VPS server, which accepts connections, and forwards the traffic down a VPN tunnel, to your home server.
|
An alternative to opening ports and directing users straight to your home router, you can use a VPN as a gateway. This allows you to forward ports to inside your home, but without actually port forwarding. No modifications to your home network are necessary. Users are pointed towards a VPS server, which accepts connections, and forwards the traffic down a VPN tunnel, to your home server.
|
||||||
|
|
||||||
Because the VPS is doing nothing but pushing traffic, there's almost no resource usage. My gateway server is a 1 core, 512mb RAM machine and it sits at around 1% CPU usage, and about 60mb RAM.
|
Because the VPS is doing nothing but pushing traffic, there's almost no resource usage. My gateway server is a one core, 512mb RAM machine and it sits at around 1% CPU usage, and about 60mb RAM.
|
||||||
|
|
||||||
By using a VPS as a gateway, there's no need to account for dynamic IPs. If your home IP changes, the VPN client in your home will have reconnected to the server automatically, and traffic continue to flow. Users never need to know or care what your home IP is, as traffic always flows via the VPS.
|
By using a VPS as a gateway, there's no need to account for dynamic IPs. If your home IP changes, the VPN client in your home will have reconnected to the server automatically, and traffic continue to flow. Users never need to know or care what your home IP is, as traffic always flows via the VPS.
|
||||||
|
|
||||||
|
@ -199,4 +199,4 @@ There's many reasons to expose your lab to the internet. Access to your services
|
||||||
|
|
||||||
Personally, I run a VPN gateway on [Vultr](https://www.vultr.com/?ref=7167289), and it works really well for my needs. If I don't want a service exposed to the public, I can connect to the VPN tunnel myself and access applications through that.
|
Personally, I run a VPN gateway on [Vultr](https://www.vultr.com/?ref=7167289), and it works really well for my needs. If I don't want a service exposed to the public, I can connect to the VPN tunnel myself and access applications through that.
|
||||||
|
|
||||||
Like many other things, there's no 1 right way to expose your homelab, there's always tradeoffs. Hopefully now you've got everything you need to make an informed decision.
|
Like many other things, there's no one right way to expose your homelab, there's always tradeoffs. Hopefully now you've got everything you need to make an informed decision.
|
||||||
|
|
|
@ -15,7 +15,7 @@ It's now 2019, and my plan for this new year is to slowly go through my Facebook
|
||||||
|
|
||||||
### Cleaning up posts - Facebook memories
|
### Cleaning up posts - Facebook memories
|
||||||
|
|
||||||
[Facebook memories](https://www.facebook.com/help/439014052921484/) shows you things you did on Facebook on this day day in previous years. Using this, you can go through things posted to your Facebook, and delete them, slowly but surely. Spending a minute or so a day over the course of a year to clean up Facebook really works! I've been doing this for just over 2 weeks, and I've already deleted 22 posts!
|
[Facebook memories](https://www.facebook.com/help/439014052921484/) shows you things you did on Facebook on this day day in previous years. Using this, you can go through things posted to your Facebook, and delete them, slowly but surely. Spending a minute or so a day over the course of a year to clean up Facebook really works! I've been doing this for just over two weeks, and I've already deleted 22 posts!
|
||||||
|
|
||||||
### Unliking pages
|
### Unliking pages
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ The issue is caused by a lack of `A2DP`, a Bluetooth profile for transmitting st
|
||||||
After a large amount of searching, I came across a number of solutions, none of which worked. From trying some alternative software, to modifying config for `bluetoothd`, no change.
|
After a large amount of searching, I came across a number of solutions, none of which worked. From trying some alternative software, to modifying config for `bluetoothd`, no change.
|
||||||
|
|
||||||
## The Solution
|
## The Solution
|
||||||
If there's 1 thing I know, it's that there's an [AUR](https://aur.archlinux.org/) package for just about everything. Surprisingly, there was even a package which fixed my issue entirely: [`pulseaudio-bluetooth-a2dp-gdm-fix`](https://aur.archlinux.org/packages/pulseaudio-bluetooth-a2dp-gdm-fix/).
|
If there's one thing I know, it's that there's an [AUR](https://aur.archlinux.org/) package for just about everything. Surprisingly, there was even a package which fixed my issue entirely: [`pulseaudio-bluetooth-a2dp-gdm-fix`](https://aur.archlinux.org/packages/pulseaudio-bluetooth-a2dp-gdm-fix/).
|
||||||
|
|
||||||
### Fixing
|
### Fixing
|
||||||
1. `yaourt -S pulseaudio-bluetooth-a2dp-gdm-fix`
|
1. `yaourt -S pulseaudio-bluetooth-a2dp-gdm-fix`
|
||||||
|
|
|
@ -11,7 +11,7 @@ A quick internet search shows a plethora of alternatives which respect privacy,
|
||||||
|
|
||||||
- [Matomo](https://matomo.org/) is bulky, and overkill for what I need. Not to mention tracks _way_ too much!
|
- [Matomo](https://matomo.org/) is bulky, and overkill for what I need. Not to mention tracks _way_ too much!
|
||||||
- [Fathom](https://usefathom.com/) used to be great, but is now closed source, and the previous "community edition" codebase has little support and is pretty buggy
|
- [Fathom](https://usefathom.com/) used to be great, but is now closed source, and the previous "community edition" codebase has little support and is pretty buggy
|
||||||
- [GoatCounter](https://www.goatcounter.com/) is 1 instance per site, and is a bit weird to work with. And then there's the name.
|
- [GoatCounter](https://www.goatcounter.com/) is one instance per site, and is a bit weird to work with. And then there's the name.
|
||||||
|
|
||||||
## Enter GoAccess
|
## Enter GoAccess
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ tags: [programming]
|
||||||
|
|
||||||
# Hacktoberfest 2019
|
# Hacktoberfest 2019
|
||||||
|
|
||||||
This is year number 3 of my participation in [Hacktoberfest](https://hacktoberfest.digitalocean.com/), the initiative from DigitalOcean, and new this year, [Dev.to](https://dev.to/). In previous years, the objective was to submit 5 pull requests to an open-source project. This year, the number was reduced to 4, for some reason.
|
This is year number three of my participation in [Hacktoberfest](https://hacktoberfest.digitalocean.com/), the initiative from DigitalOcean, and new this year, [Dev.to](https://dev.to/). In previous years, the objective was to submit five pull requests to an open-source project. This year, the number was reduced to four, for some reason.
|
||||||
|
|
||||||
In [2018]({{< relref "hacktoberfest-2018" >}}), I submitted a total of 10 pull requests to open-source projects. This year, I did a few more than that.
|
In [2018]({{< relref "hacktoberfest-2018" >}}), I submitted a total of 10 pull requests to open-source projects. This year, I did a few more than that.
|
||||||
|
|
||||||
|
|
|
@ -28,11 +28,11 @@ If you get breached, and your password database is stolen, then the attacker can
|
||||||
|
|
||||||
## Hashing
|
## Hashing
|
||||||
|
|
||||||
A hash is a way of converting 1 value into another in such a way it's impossible to reverse.
|
A hash is a way of converting one value into another in such a way it's impossible to reverse.
|
||||||
|
|
||||||
Imagine a smoothie maker. You put fruit in, it mixes it up, and you get a smoothie out of it. Now no matter what you do, there's no machine which could take a smoothie, and give you the fruit back whole. Now yes given a smoothie you could probably tell me which kinds of fruits are in there, but what about which *specific* fruits? Given a strawberry smoothie, and a picture of a million strawberries, could you tell me which strawberries were in there?
|
Imagine a smoothie maker. You put fruit in, it mixes it up, and you get a smoothie out of it. Now no matter what you do, there's no machine which could take a smoothie, and give you the fruit back whole. Now yes given a smoothie you could probably tell me which kinds of fruits are in there, but what about which *specific* fruits? Given a strawberry smoothie, and a picture of a million strawberries, could you tell me which strawberries were in there?
|
||||||
|
|
||||||
An interesting characteristic of passwords is that that 2 slightly similar inputs can give completely different answers.
|
An interesting characteristic of passwords is that that two slightly similar inputs can give completely different answers.
|
||||||
|
|
||||||
There are many different hashing algorithms, although the most common are the SHA family, specifically SHA265 and SHA512. SHA1 and MD5 are whilst better than nothing, considered insecure. Base64 is not a hash!
|
There are many different hashing algorithms, although the most common are the SHA family, specifically SHA265 and SHA512. SHA1 and MD5 are whilst better than nothing, considered insecure. Base64 is not a hash!
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ When storing a users' password, rather than storing the password, you store the
|
||||||
|
|
||||||
Whilst hashes aren't reversible directly, you can just search for them. Take the value `{{< md5 "foobar" >}}`. You can't take that value and reverse it back into the input `foobar`, but you can literally [search it online](https://duckduckgo.com/?q={{< md5 "foobar" >}}) and find the result. This is thanks to rainbow tables.
|
Whilst hashes aren't reversible directly, you can just search for them. Take the value `{{< md5 "foobar" >}}`. You can't take that value and reverse it back into the input `foobar`, but you can literally [search it online](https://duckduckgo.com/?q={{< md5 "foobar" >}}) and find the result. This is thanks to rainbow tables.
|
||||||
|
|
||||||
Rainbow are a huge table of mappings between hashes and their plaintext counterparts. Bruteforcing a hash can take a long time, but looking up a hash in a rainbow table will take a few seconds at most. The rainbow table for 7 letter passwords hashed with SHA1 is just 50GB. [Project rainbowcrack](https://project-rainbowcrack.com/table.htm) has a list of them for download.
|
Rainbow are a huge table of mappings between hashes and their plaintext counterparts. Bruteforcing a hash can take a long time, but looking up a hash in a rainbow table will take a few seconds at most. The rainbow table for seven letter passwords hashed with SHA1 is just 50GB. [Project rainbowcrack](https://project-rainbowcrack.com/table.htm) has a list of them for download.
|
||||||
|
|
||||||
Hashing also has the drawback of repeatability. Given the same input, a hash will always return the same output. This means that if people are using the same password, they'll have the same hash. Combined with things like password resets, it can become fairly simple to work them out, and [fun](https://xkcd.com/1286/).
|
Hashing also has the drawback of repeatability. Given the same input, a hash will always return the same output. This means that if people are using the same password, they'll have the same hash. Combined with things like password resets, it can become fairly simple to work them out, and [fun](https://xkcd.com/1286/).
|
||||||
|
|
||||||
|
@ -50,7 +50,7 @@ Hashing also has the drawback of repeatability. Given the same input, a hash wil
|
||||||
|
|
||||||
Want to make your food taste stronger? Add salt to it. Want to make your hashing stronger, [add salt to it](https://auth0.com/blog/adding-salt-to-hashing-a-better-way-to-store-passwords/)!
|
Want to make your food taste stronger? Add salt to it. Want to make your hashing stronger, [add salt to it](https://auth0.com/blog/adding-salt-to-hashing-a-better-way-to-store-passwords/)!
|
||||||
|
|
||||||
The idea of a salt is to prevent the 2 main shortcomings with hashing on its own: Users with the same password having the same hash, and rainbow tables. It does this in the same way.
|
The idea of a salt is to prevent the two main shortcomings with hashing on its own: Users with the same password having the same hash, and rainbow tables. It does this in the same way.
|
||||||
|
|
||||||
A salt is an additional piece of information added into the hashing process. By ensuring the salt is different for each user, even users with the same password would have a different password hash. Some people use the users email address as a salt, but really it should be a completely random value. The important thing is that it's completely different for users.
|
A salt is an additional piece of information added into the hashing process. By ensuring the salt is different for each user, even users with the same password would have a different password hash. Some people use the users email address as a salt, but really it should be a completely random value. The important thing is that it's completely different for users.
|
||||||
|
|
||||||
|
@ -80,7 +80,7 @@ Key derivation is designed to be slow - Not critically slow, but slow enough. Th
|
||||||
|
|
||||||
Once a user has logged in, you've hashed their password using only the best practices, you've pulled what their password should be from the database, it's time to compare them. They're both strings, so `==` should work, right? Well yes, but actually no. Comparing strings is incredibly well optimised, for good reason! Lots of fundamental parts of programming depend on strings being compared as quickly as possible. However when it comes to security, this isn't necessarily what we want.
|
Once a user has logged in, you've hashed their password using only the best practices, you've pulled what their password should be from the database, it's time to compare them. They're both strings, so `==` should work, right? Well yes, but actually no. Comparing strings is incredibly well optimised, for good reason! Lots of fundamental parts of programming depend on strings being compared as quickly as possible. However when it comes to security, this isn't necessarily what we want.
|
||||||
|
|
||||||
Many methods of string comparison have a number of cases to short circuit, and run faster than a regular character-by-character comparison. Even then when running a character-by-character comparison, it's good practice to abort as soon as you've got 1 character which doesn't match. When comparing hashes, these short circuits are counter-productive. By accurately measuring how long the system takes to check your password, you can gain insight about what the true hashes value is, and therefore begin to crack it. This is known as a [timing attack](https://en.wikipedia.org/wiki/Timing_attack).
|
Many methods of string comparison have a number of cases to short circuit, and run faster than a regular character-by-character comparison. Even then when running a character-by-character comparison, it's good practice to abort as soon as you've got one character which doesn't match. When comparing hashes, these short circuits are counter-productive. By accurately measuring how long the system takes to check your password, you can gain insight about what the true hashes value is, and therefore begin to crack it. This is known as a [timing attack](https://en.wikipedia.org/wiki/Timing_attack).
|
||||||
|
|
||||||
Any time you're comparing values in a secure context, you should a constant-time algorithm. The time required for these is always relative to the length of the values, and doesn't short circuit. For example, like the following Python:
|
Any time you're comparing values in a secure context, you should a constant-time algorithm. The time required for these is always relative to the length of the values, and doesn't short circuit. For example, like the following Python:
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ The settings I'm using for my database
|
||||||
{{< /resource >}}
|
{{< /resource >}}
|
||||||
|
|
||||||
### Mobile
|
### Mobile
|
||||||
If you're planning to use your database on less-powerful hardware, such as a phone, you'll want to set the transformation rounds low. Argon2 is far more computationally intensive compared to PBKDF2. Using the 1-second benchmark button suggests using just 23 rounds. Where before I used 20,000 rounds of PBKDF2, I now use just 5 rounds of Argon2, to ensure it opens in reasonable time on my phone.
|
If you're planning to use your database on less-powerful hardware, such as a phone, you'll want to set the transformation rounds low. Argon2 is far more computationally intensive compared to PBKDF2. Using the 1-second benchmark button suggests using just 23 rounds. Where before I used 20,000 rounds of PBKDF2, I now use just five rounds of Argon2, to ensure it opens in reasonable time on my phone.
|
||||||
|
|
||||||
## New Key Files
|
## New Key Files
|
||||||
The new key file format enables using any file as a key file for your database, rather than the XML format. This means rather than using a 45-bit key in an XML file, you can use any file of any size.
|
The new key file format enables using any file as a key file for your database, rather than the XML format. This means rather than using a 45-bit key in an XML file, you can use any file of any size.
|
||||||
|
@ -55,7 +55,7 @@ To use the new key, you need to change the key file in the master key settings (
|
||||||
Once the key is installed, I backed up the old key offline (just in case), and deleted it.
|
Once the key is installed, I backed up the old key offline (just in case), and deleted it.
|
||||||
|
|
||||||
## Native Messaging
|
## Native Messaging
|
||||||
Native messaging is a way of 2 processes communicating in a secure-ish manor. In this case, it means the browser can communicate with KeePassXC in a way that means other applications can't.
|
Native messaging is a way of two processes communicating in a secure-ish manor. In this case, it means the browser can communicate with KeePassXC in a way that means other applications can't.
|
||||||
|
|
||||||
Before, the browser communicated with KeePassXC over HTTP, using the [KeePassHTTP](https://github.com/pfn/keepasshttp) protocol. This had the benefit of being very easy to implement a client for, as it's just standard web traffic. The down side is that it involved starting a web server on an internal port, meaning any process on your computer could connect to the web server and thus communicate with KeePassXC, this includes browser sessions. Although requests had to be signed, it still isn't very good for security.
|
Before, the browser communicated with KeePassXC over HTTP, using the [KeePassHTTP](https://github.com/pfn/keepasshttp) protocol. This had the benefit of being very easy to implement a client for, as it's just standard web traffic. The down side is that it involved starting a web server on an internal port, meaning any process on your computer could connect to the web server and thus communicate with KeePassXC, this includes browser sessions. Although requests had to be signed, it still isn't very good for security.
|
||||||
|
|
||||||
|
|
|
@ -3,9 +3,9 @@ title: macOS - A Linux Guys Perspective
|
||||||
date: 2019-10-01
|
date: 2019-10-01
|
||||||
---
|
---
|
||||||
|
|
||||||
For the last 4 years, I've been spending every working day off a Dell Optiplex. With an after-market SSD upgrade, and a little extra memory, it makes a pretty good work machine. When it comes to needing to work away from my desk, it's a little annoying having only a desktop. For the last 10 months, I've been asking for a laptop which, because _reasons_, has to be a macbook.
|
For the last four years, I've been spending every working day off a Dell Optiplex. With an after-market SSD upgrade, and a little extra memory, it makes a pretty good work machine. When it comes to needing to work away from my desk, it's a little annoying having only a desktop. For the last 10 months, I've been asking for a laptop which, because _reasons_, has to be a macbook.
|
||||||
|
|
||||||
Last week, I got my macbook! With 1 condition: I had to give macOS a try, for a whole week. And so, with every intention of installing Linux on it afterwards, I gave it a shot.
|
Last week, I got my macbook! With one condition: I had to give macOS a try, for a whole week. And so, with every intention of installing Linux on it afterwards, I gave it a shot.
|
||||||
|
|
||||||
## The Review
|
## The Review
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ Historically, package installation on macOS has been in the form of `.dmg` files
|
||||||
|
|
||||||
`brew` is the command-line package manager for macOS, allowing simple installation of almost any application and service for macOS. `brew cask` is an extension for this, designed specifically for GUI applications. It also means each application has to update in its own special way.
|
`brew` is the command-line package manager for macOS, allowing simple installation of almost any application and service for macOS. `brew cask` is an extension for this, designed specifically for GUI applications. It also means each application has to update in its own special way.
|
||||||
|
|
||||||
As someone who's used to the AUR, this felt great! 1 command to install and update almost any application I need.
|
As someone who's used to the AUR, this felt great! one command to install and update almost any application I need.
|
||||||
|
|
||||||
#### Global emoji-picker is awesome!
|
#### Global emoji-picker is awesome!
|
||||||
|
|
||||||
|
@ -87,7 +87,7 @@ Apple maintain a comprehensive, but unnecessarily complex [support page](https:/
|
||||||
|
|
||||||
Just, WHY?!
|
Just, WHY?!
|
||||||
|
|
||||||
Trackpad acceleration feels reasonably natural, flicking around content as if you're actually touching it. On a scroll-wheel, not so much. It just means depending on how quickly you're scrolling, 1 notch could be 1 line or several, it depends on how the OS is feeling. I use an MX Master, which has a ratchet-free scrolling mode, which makes the acceleration even more noticeable, and even more annoying.
|
Trackpad acceleration feels reasonably natural, flicking around content as if you're actually touching it. On a scroll-wheel, not so much. It just means depending on how quickly you're scrolling, one notch could be one line or several, it depends on how the OS is feeling. I use an MX Master, which has a ratchet-free scrolling mode, which makes the acceleration even more noticeable, and even more annoying.
|
||||||
|
|
||||||
What's more, is that whilst you can disable trackpad scrolling, you can't disable scroll-wheel acceleration, not without using 3rd-party applications, many of which look like somewhat hacky scripts (not that I'm against those!).
|
What's more, is that whilst you can disable trackpad scrolling, you can't disable scroll-wheel acceleration, not without using 3rd-party applications, many of which look like somewhat hacky scripts (not that I'm against those!).
|
||||||
|
|
||||||
|
|
|
@ -6,11 +6,11 @@ date: 2019-05-29
|
||||||
|
|
||||||
I've been an arch user for many years, and a linux user for even longer, but I've never installed arch from scratch. I was an Antergos user for many years, but after its demise, I needed an alternative. In a [previous post]({{< relref replacing-antergos >}}), I spoke of attempting to install vanilla arch from scratch on my laptop. As I write this, it works well, really well. Everything installed correctly, complete with EFI boot, encrypted partitions and sleep state.
|
I've been an arch user for many years, and a linux user for even longer, but I've never installed arch from scratch. I was an Antergos user for many years, but after its demise, I needed an alternative. In a [previous post]({{< relref replacing-antergos >}}), I spoke of attempting to install vanilla arch from scratch on my laptop. As I write this, it works well, really well. Everything installed correctly, complete with EFI boot, encrypted partitions and sleep state.
|
||||||
|
|
||||||
Speaking to those who have installed arch before, they say _"oh, it's simple"_ and _"it only takes like 20 minutes"_. Both those statements are wrong! To go from booting into an arch ISO to a login shell of a remotely usable system took around 3 hours, and countless browser tabs. I hit a lot of hurdles which, in hindsight, I definitely should have seen coming, and almost certainly already knew. But if they tripped me up, they'll almost certainly have tripped someone else up.
|
Speaking to those who have installed arch before, they say _"oh, it's simple"_ and _"it only takes like 20 minutes"_. Both those statements are wrong! To go from booting into an arch ISO to a login shell of a remotely usable system took around three hours, and countless browser tabs. I hit a lot of hurdles which, in hindsight, I definitely should have seen coming, and almost certainly already knew. But if they tripped me up, they'll almost certainly have tripped someone else up.
|
||||||
|
|
||||||
## Gotchas
|
## Gotchas
|
||||||
|
|
||||||
So here's my 1 stop shop of the things which caught me up during the install and setup process. Whilst I did this install on my [XPS 15], it's all pretty generic.
|
So here's my one stop shop of the things which caught me up during the install and setup process. Whilst I did this install on my [XPS 15], it's all pretty generic.
|
||||||
|
|
||||||
### Use a wired network
|
### Use a wired network
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ I use a standard UK-ISO layout, which isn't the default on the arch installer. I
|
||||||
|
|
||||||
Many applications I use are installed from the AUR, it's the main reason I switched to arch in the first place. To my knowledge, there are no AUR helpers available in any of the default repos. Antergos provided `yay`, my AUR tool of choice, in their additional repo. Because Antergos is no more, and I don't want to install a package from a _deprecated_ repo, I had to install it manually using `makepkg`.
|
Many applications I use are installed from the AUR, it's the main reason I switched to arch in the first place. To my knowledge, there are no AUR helpers available in any of the default repos. Antergos provided `yay`, my AUR tool of choice, in their additional repo. Because Antergos is no more, and I don't want to install a package from a _deprecated_ repo, I had to install it manually using `makepkg`.
|
||||||
|
|
||||||
The `yay` git repository has [instructions](https://github.com/Jguer/yay#installation) on how to do this, but it's quite literally 3 commands!
|
The `yay` git repository has [instructions](https://github.com/Jguer/yay#installation) on how to do this, but it's quite literally three commands!
|
||||||
|
|
||||||
After this, `yay` will update itself from the AUR package once an update is available.
|
After this, `yay` will update itself from the AUR package once an update is available.
|
||||||
|
|
||||||
|
@ -64,4 +64,4 @@ For my install, there were a couple of sites I used in particular which were use
|
||||||
|
|
||||||
Once the installation was complete, it was as simple as cloning [my dotfiles]({{< relref dotfiles >}}), and waiting for a complete system. There were a couple of issues with that, but mostly because of packages previously installed with Antergos, which I now had to explicitly install.
|
Once the installation was complete, it was as simple as cloning [my dotfiles]({{< relref dotfiles >}}), and waiting for a complete system. There were a couple of issues with that, but mostly because of packages previously installed with Antergos, which I now had to explicitly install.
|
||||||
|
|
||||||
1 machine down, 3 to go...
|
One machine down, three to go...
|
||||||
|
|
|
@ -8,7 +8,7 @@ hide_header_image: true
|
||||||
As a software engineer and perfectionist, I have my machines setup in a very specific way, so I can do my job properly and have everything just the way I like it. Thanks to my [dotfiles]({{< relref "projects/dotfiles" >}}), I have everything syncing up between machines, meaning the tools I use are setup correctly, the same, everywhere.
|
As a software engineer and perfectionist, I have my machines setup in a very specific way, so I can do my job properly and have everything just the way I like it. Thanks to my [dotfiles]({{< relref "projects/dotfiles" >}}), I have everything syncing up between machines, meaning the tools I use are setup correctly, the same, everywhere.
|
||||||
|
|
||||||
# OS
|
# OS
|
||||||
My current distro of choice is [Arch](https://www.archlinux.org/), specifically [Antergos](https://antergos.com/). My main reason for choosing arch is the [AUR](https://aur.archlinux.org/). Almost every package I can think of is packaged there, often by the community. It's great to be able to install things through 1 method and have everything update in a single command. Antergos is also far easier to install than raw arch, and has little to no bloat that comes with it.
|
My current distro of choice is [Arch](https://www.archlinux.org/), specifically [Antergos](https://antergos.com/). My main reason for choosing arch is the [AUR](https://aur.archlinux.org/). Almost every package I can think of is packaged there, often by the community. It's great to be able to install things through one method and have everything update in a single command. Antergos is also far easier to install than raw arch, and has little to no bloat that comes with it.
|
||||||
|
|
||||||
## Desktop
|
## Desktop
|
||||||
My current desktop of choice is [i3](https://i3wm.org/). After spending a lot of time using [Gnome](https://www.gnome.org/), and always having windows either full screen or split, I tried out i3 in an attempt to use fewer resources, and it's amazing. Admittedly i3 doesn't look quite as nice, but it's far cleaner, and structured, and that's enough for me!
|
My current desktop of choice is [i3](https://i3wm.org/). After spending a lot of time using [Gnome](https://www.gnome.org/), and always having windows either full screen or split, I tried out i3 in an attempt to use fewer resources, and it's amazing. Admittedly i3 doesn't look quite as nice, but it's far cleaner, and structured, and that's enough for me!
|
||||||
|
@ -19,7 +19,7 @@ Editing my stack, in caret
|
||||||
|
|
||||||
# Editors
|
# Editors
|
||||||
## Code
|
## Code
|
||||||
My primary editor is [IntelliJ](https://www.jetbrains.com/idea/). [PyCharm](https://www.jetbrains.com/pycharm/) would be a better fit, as I spend much of my time writing Python, but as I have a strong dislike of Jetbrains' approach of having [an editor per language](https://www.jetbrains.com/products.html), IntelliJ has the best support for all languages, in 1 editor. As an IDE, it has more features than I could ever need, and is more than fast enough for editing the large projects I work on. I have a fairly large number of plugins installed, and even more of the default ones disabled.
|
My primary editor is [IntelliJ](https://www.jetbrains.com/idea/). [PyCharm](https://www.jetbrains.com/pycharm/) would be a better fit, as I spend much of my time writing Python, but as I have a strong dislike of Jetbrains' approach of having [an editor per language](https://www.jetbrains.com/products.html), IntelliJ has the best support for all languages, in one editor. As an IDE, it has more features than I could ever need, and is more than fast enough for editing the large projects I work on. I have a fairly large number of plugins installed, and even more of the default ones disabled.
|
||||||
|
|
||||||
## Markdown
|
## Markdown
|
||||||
[Caret](https://caret.io/) is absolutely awesome! The fact it's not open source does hurt a little. Compared to [ghostwriter](https://wereturtle.github.io/ghostwriter/), which is both free and open source, it's got some far nicer features such as a command palette and true live reload. Version 4 is [coming soon](https://twitter.com/careteditor/status/943816379618250752), hopefully this brings yet more features, but I fear asking for it to be open-sourced is going too far!
|
[Caret](https://caret.io/) is absolutely awesome! The fact it's not open source does hurt a little. Compared to [ghostwriter](https://wereturtle.github.io/ghostwriter/), which is both free and open source, it's got some far nicer features such as a command palette and true live reload. Version 4 is [coming soon](https://twitter.com/careteditor/status/943816379618250752), hopefully this brings yet more features, but I fear asking for it to be open-sourced is going too far!
|
||||||
|
|
|
@ -26,7 +26,7 @@ Flameshot in action
|
||||||
My primarily editor is now [VSCode](https://code.visualstudio.com/), because it's faster and lighter-weight than IntelliJ. All the features I need from a large editor, but doesn't take 10 minutes to load! Because VSCode stores its configuration in plain files, in a very simple way, it's easy to sync it between machines, [which I do](https://github.com/RealOrangeOne/dotfiles/blob/master/tasks/vscode.yml).
|
My primarily editor is now [VSCode](https://code.visualstudio.com/), because it's faster and lighter-weight than IntelliJ. All the features I need from a large editor, but doesn't take 10 minutes to load! Because VSCode stores its configuration in plain files, in a very simple way, it's easy to sync it between machines, [which I do](https://github.com/RealOrangeOne/dotfiles/blob/master/tasks/vscode.yml).
|
||||||
|
|
||||||
## Markdown
|
## Markdown
|
||||||
Last year, I was a fan of [Caret](https://caret.io/), and was eagerly awaiting version 4, which was in beta last year. 1 year on, and still no closer to seeing anything. It's for that reason I've switched back to [GhostWriter](https://github.com/wereturtle/ghostwriter/). Also because free and open source is great!
|
Last year, I was a fan of [Caret](https://caret.io/), and was eagerly awaiting version 4, which was in beta last year. one year on, and still no closer to seeing anything. It's for that reason I've switched back to [GhostWriter](https://github.com/wereturtle/ghostwriter/). Also because free and open source is great!
|
||||||
|
|
||||||
## Quick files edits
|
## Quick files edits
|
||||||
Nothing beats [Vim](http://www.vim.org/) for anything like this. I've switched my default editor for git commit messages, and have it installed on all my servers. I'm still unfamiliar with many of the advanced keyboard shortcuts, but I can navigate around a file just well enough for me.
|
Nothing beats [Vim](http://www.vim.org/) for anything like this. I've switched my default editor for git commit messages, and have it installed on all my servers. I'm still unfamiliar with many of the advanced keyboard shortcuts, but I can navigate around a file just well enough for me.
|
||||||
|
@ -64,7 +64,7 @@ After realising that the benefits of [Mailfence](https://mailfence.com/) weren't
|
||||||
My email client has stayed the same. There really is nothing close to [Thunderbird](https://www.thunderbird.net/en-GB/) on Linux! Mailspring does look nice, but it's still not quite feature-complete for my needs. And the fact Thunderbird is also a calendar app is quite useful too!
|
My email client has stayed the same. There really is nothing close to [Thunderbird](https://www.thunderbird.net/en-GB/) on Linux! Mailspring does look nice, but it's still not quite feature-complete for my needs. And the fact Thunderbird is also a calendar app is quite useful too!
|
||||||
|
|
||||||
# RSS
|
# RSS
|
||||||
It might seem outdated, but I still quite like RSS. For me, it acts as a nice way to read content from various sources, all in 1 place. I can also use it to watch YouTube videos, without having to deal with YouTube itself! [FreshRSS](https://www.freshrss.org/) is my aggregator of choice, with [FeedReader](https://jangernert.github.io/FeedReader/) as the desktop client. I tried [Tiny Tiny RSS](https://tt-rss.org/), but the UI didn't work for me.
|
It might seem outdated, but I still quite like RSS. For me, it acts as a nice way to read content from various sources, all in one place. I can also use it to watch YouTube videos, without having to deal with YouTube itself! [FreshRSS](https://www.freshrss.org/) is my aggregator of choice, with [FeedReader](https://jangernert.github.io/FeedReader/) as the desktop client. I tried [Tiny Tiny RSS](https://tt-rss.org/), but the UI didn't work for me.
|
||||||
|
|
||||||
# Mobile Podcast Player
|
# Mobile Podcast Player
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ Another unfortunate side-effect of the new WYSIWYG text editor, is the lack of a
|
||||||
|
|
||||||
## Restoring the previous UI
|
## Restoring the previous UI
|
||||||
|
|
||||||
Fortunately, it's possible to restore the old UI in all its glory, with the installation of 2 extra apps. Disable the Text extension, enable these, and you'll be good to go!
|
Fortunately, it's possible to restore the old UI in all its glory, with the installation of two extra apps. Disable the Text extension, enable these, and you'll be good to go!
|
||||||
|
|
||||||
### [`files_texteditor`](https://github.com/nextcloud/files_texteditor/)
|
### [`files_texteditor`](https://github.com/nextcloud/files_texteditor/)
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ Both `true` and `false` are incredibly simple, even if you nothing about C. And
|
||||||
|
|
||||||
`nologin` does a little more than false, but it's still very simple code to read: [`nologin.c`](https://git.kernel.org/pub/scm/utils/util-linux/util-linux.git/tree/login-utils/nologin.c)
|
`nologin` does a little more than false, but it's still very simple code to read: [`nologin.c`](https://git.kernel.org/pub/scm/utils/util-linux/util-linux.git/tree/login-utils/nologin.c)
|
||||||
|
|
||||||
Once executed, `nologin` will try and read `/etc/nologin.txt` to get a custom message to show the user. If it exists, it prints that and exits with code 1. If it doesn't exist, it shows the default message, and exits with code 1. This customization makes it much more user friendly, although because the file is global, 1 system can only have 1 configured message.
|
Once executed, `nologin` will try and read `/etc/nologin.txt` to get a custom message to show the user. If it exists, it prints that and exits with code 1. If it doesn't exist, it shows the default message, and exits with code 1. This customization makes it much more user friendly, although because the file is global, one system can only have one configured message.
|
||||||
|
|
||||||
## `rssh`
|
## `rssh`
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ For reasons unknown, only HTTP ports (80, 443) are available from machines other
|
||||||
With coursework requiring deployment onto this server now, access to SSH is essential (besides FTP, but who really wants to use that?). But, how to get SSH access to a server, without needing to use the terrible _RemoteApp_?
|
With coursework requiring deployment onto this server now, access to SSH is essential (besides FTP, but who really wants to use that?). But, how to get SSH access to a server, without needing to use the terrible _RemoteApp_?
|
||||||
|
|
||||||
## SSH Reverse Tunnels
|
## SSH Reverse Tunnels
|
||||||
SSH has the ability to create a reverse tunnel between 2 machines, by using a 3rd as a gateway. Assuming the destination server has the ability to SSH out of its firewall, a separate SSH connection can use that connection as a tunnel to communicate.
|
SSH has the ability to create a reverse tunnel between two machines, by using a 3rd as a gateway. Assuming the destination server has the ability to SSH out of its firewall, a separate SSH connection can use that connection as a tunnel to communicate.
|
||||||
|
|
||||||
{{<mermaid caption="Network layout">}}
|
{{<mermaid caption="Network layout">}}
|
||||||
graph LR
|
graph LR
|
||||||
|
|
|
@ -10,7 +10,7 @@ Throughout my life, I've had many different email providers, starting with [Hotm
|
||||||
|
|
||||||
Originally I thought the best way to keep things secure, and out of the hands of any government body was to host it all myself. This came with a number of problems, mostly due to my lack of experience running anything like this, which lead to problems with my spam filter blocking legitimate emails, and any emails I did send ending up in their spam folder.
|
Originally I thought the best way to keep things secure, and out of the hands of any government body was to host it all myself. This came with a number of problems, mostly due to my lack of experience running anything like this, which lead to problems with my spam filter blocking legitimate emails, and any emails I did send ending up in their spam folder.
|
||||||
|
|
||||||
After searching around for a while, I stumbled on _ProtonMail_, who claimed to be the most secure email host ever. One of their founders did a [TED talk](https://www.ted.com/talks/andy_yen_think_your_email_s_private_think_again), which sold me on the platform.
|
After searching around for a while, I stumbled on _ProtonMail_, who claimed to be the most secure email host ever. One of their founders did a [TED talk](https://www.ted.com/talks/andy_yen_think_your_email_s_private_think_again), which sold me on the platform.
|
||||||
|
|
||||||
ProtonMail use a combination of [open-source technologies](https://github.com/protonmail), a closed-access platform, and swiss data centers to protect emails better than anyone else! The only way you can access your emails is by using their custom apps for Android, iOS, and web. Whilst this is annoying, and means it isn't accessible through protocols such as IMAP and POP3, which would considerably lower the security.
|
ProtonMail use a combination of [open-source technologies](https://github.com/protonmail), a closed-access platform, and swiss data centers to protect emails better than anyone else! The only way you can access your emails is by using their custom apps for Android, iOS, and web. Whilst this is annoying, and means it isn't accessible through protocols such as IMAP and POP3, which would considerably lower the security.
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ ProtonMail as a system is fantastic! So far it's had 0 downtime, never missed a
|
||||||
# The Problems
|
# The Problems
|
||||||
I knew ProtonMail was missing some features, but when I committed, I didn't think I'd need them. It's funny just how little you think you need a feature, until you don't have the option.
|
I knew ProtonMail was missing some features, but when I committed, I didn't think I'd need them. It's funny just how little you think you need a feature, until you don't have the option.
|
||||||
|
|
||||||
Now, 3 months on, I'm starting to get a little annoyed at ProtonMail, mainly at their lack of features. Yes the security is great, really great, but the fact I have to open a website and login every time I want to check my emails is a little tiring, and their mobile app, whilst fully functional and capable of the basics, has some bugs and glitches out sometimes.
|
Now, three months on, I'm starting to get a little annoyed at ProtonMail, mainly at their lack of features. Yes the security is great, really great, but the fact I have to open a website and login every time I want to check my emails is a little tiring, and their mobile app, whilst fully functional and capable of the basics, has some bugs and glitches out sometimes.
|
||||||
|
|
||||||
Another problem is the lack of basic features. Whilst the client does have labels, and _'+ aliases'_, both of which are great features for those with email OCD, The platform is missing out on some other key features, like:
|
Another problem is the lack of basic features. Whilst the client does have labels, and _'+ aliases'_, both of which are great features for those with email OCD, The platform is missing out on some other key features, like:
|
||||||
|
|
||||||
|
@ -35,4 +35,4 @@ Another problem is the lack of basic features. Whilst the client does have label
|
||||||
|
|
||||||
These problems are taken for granted in most other mail platform, but because ProtonMail is built from the ground up, and is still a reasonably new product, it's missing a lot of these key features.
|
These problems are taken for granted in most other mail platform, but because ProtonMail is built from the ground up, and is still a reasonably new product, it's missing a lot of these key features.
|
||||||
|
|
||||||
__Update__: All the above features have either been implemented, or are being actively worked on.
|
__Update__: All the above features have either been implemented, or are being actively worked on.
|
||||||
|
|
|
@ -8,9 +8,9 @@ repo: RealOrangeOne/react-native-intro-dev-meeting
|
||||||
|
|
||||||
Recently, at DabApps, we've been migrating our mobile app workflow over to using [react-native](https://facebook.github.io/react-native/) rather than [Ionic](http://ionicframework.com/), mainly because of its near native performance. For the first few projects, there were only a couple of us that knew how to use React Native effectively, and work around the _qwerks_ it has. With the number of app projects growing, we needed to get more people up to speed with the react native workflow, as quickly as possible.
|
Recently, at DabApps, we've been migrating our mobile app workflow over to using [react-native](https://facebook.github.io/react-native/) rather than [Ionic](http://ionicframework.com/), mainly because of its near native performance. For the first few projects, there were only a couple of us that knew how to use React Native effectively, and work around the _qwerks_ it has. With the number of app projects growing, we needed to get more people up to speed with the react native workflow, as quickly as possible.
|
||||||
|
|
||||||
The workflow that we needed to adopt to use react native is an odd one. To keep the quality of our code at the highest possible, whilst keeping the codebase as maintainable as possible. The workflow we use was created by 4 of us, through experiences with both work and personal projects using the framework, and it works rather well. The only problem was that only 4 of us actually knew it.
|
The workflow that we needed to adopt to use react native is an odd one. To keep the quality of our code at the highest possible, whilst keeping the codebase as maintainable as possible. The workflow we use was created by four of us, through experiences with both work and personal projects using the framework, and it works rather well. The only problem was that only four of us actually knew it.
|
||||||
|
|
||||||
After a colleague wanted to know more about react-native, and with a couple of potential app projects on the horizon, I created a talk for our (_usually_) bi-weekly dev meetings, with the aim of trying to get everyone up to speed, all in 1 go.
|
After a colleague wanted to know more about react-native, and with a couple of potential app projects on the horizon, I created a talk for our (_usually_) bi-weekly dev meetings, with the aim of trying to get everyone up to speed, all in one go.
|
||||||
|
|
||||||
The slides from my talk are available on my [GitHub](https://github.com/RealOrangeOne/react-native-intro-dev-meeting) page, and whilst they are primarily relevant to our workflow, I hope they will be able to help anyone else looking to get started with React Native.
|
The slides from my talk are available on my [GitHub](https://github.com/RealOrangeOne/react-native-intro-dev-meeting) page, and whilst they are primarily relevant to our workflow, I hope they will be able to help anyone else looking to get started with React Native.
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ image: https://antergos.com/wp-content/uploads/2014/09/antergos-wallpaper.png
|
||||||
tags: [arch]
|
tags: [arch]
|
||||||
---
|
---
|
||||||
|
|
||||||
I've been an [Antergos](https://antergos.com/) user for almost 3 years, and I love it! It's like Arch, but with a simple installation process, and yields a near-pure Arch install, unlike Arch derivatives like [Manjaro](https://manjaro.org/). Unfortunately, on 21st May 2019, the [Antergos project ended](https://antergos.com/blog/antergos-linux-project-ends/). Those behind the project were unable to commit the time the project needed and deserved. I for one want to thank them for the effort they have put in!
|
I've been an [Antergos](https://antergos.com/) user for almost three years, and I love it! It's like Arch, but with a simple installation process, and yields a near-pure Arch install, unlike Arch derivatives like [Manjaro](https://manjaro.org/). Unfortunately, on 21st May 2019, the [Antergos project ended](https://antergos.com/blog/antergos-linux-project-ends/). Those behind the project were unable to commit the time the project needed and deserved. I for one want to thank them for the effort they have put in!
|
||||||
|
|
||||||
The issue now is what to do with my machines which run Antergos (of which there are currently 5). Technically, I don't need to do anything, the Antergos team state that because existing installs are _basically_ vanilla arch, there's no need to panic and wipe:
|
The issue now is what to do with my machines which run Antergos (of which there are currently 5). Technically, I don't need to do anything, the Antergos team state that because existing installs are _basically_ vanilla arch, there's no need to panic and wipe:
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ In terms of security, [WordPress](https://wordpress.org), and PHP in general for
|
||||||
|
|
||||||
Recently, I was approached by an old friend to setup a small-scale online store and blog. After doing lots of research into cheap, static options, I eventually settled on WordPress and WooCommerce, on the advice of a colleague. Having never setup a site like this, which relies on being secure, and fairly fast, it was going to be a challenge, and doing it on a shoestring budget was going to make things harder!
|
Recently, I was approached by an old friend to setup a small-scale online store and blog. After doing lots of research into cheap, static options, I eventually settled on WordPress and WooCommerce, on the advice of a colleague. Having never setup a site like this, which relies on being secure, and fairly fast, it was going to be a challenge, and doing it on a shoestring budget was going to make things harder!
|
||||||
|
|
||||||
And so, after 2 weeks of on-and-off poking, research, re-installation and optimisation, and [an oddly timed twitter thread with @CryptoSeb](https://twitter.com/CryptoSeb/status/1035611479800721408), I eventually settled on a setup on how to do it which is secure, fast, and satisfies my inner DevOps' OCD.
|
And so, after two weeks of on-and-off poking, research, re-installation and optimisation, and [an oddly timed twitter thread with @CryptoSeb](https://twitter.com/CryptoSeb/status/1035611479800721408), I eventually settled on a setup on how to do it which is secure, fast, and satisfies my inner DevOps' OCD.
|
||||||
|
|
||||||
## OS
|
## OS
|
||||||
|
|
||||||
|
|
|
@ -15,17 +15,17 @@ At the time, my website was hosted on [Netlify](https://www.netlify.com/). If yo
|
||||||
|
|
||||||
To get the site working on my home server, the build process would need to change slightly. Netlify automatically discovers the tasks which need doing to install dependencies for your site, and then let you provide a single command to build the site. In my case, all I needed was [Hugo](https://gohugo.io/), NodeJS, and a [specific bash script](https://github.com/RealOrangeOne/theorangeone.net/blob/master/scripts/build.sh) to run. My home server runs is basically a docker host, so the site would need to run from inside a container.
|
To get the site working on my home server, the build process would need to change slightly. Netlify automatically discovers the tasks which need doing to install dependencies for your site, and then let you provide a single command to build the site. In my case, all I needed was [Hugo](https://gohugo.io/), NodeJS, and a [specific bash script](https://github.com/RealOrangeOne/theorangeone.net/blob/master/scripts/build.sh) to run. My home server runs is basically a docker host, so the site would need to run from inside a container.
|
||||||
|
|
||||||
[The container](https://github.com/RealOrangeOne/theorangeone.net/blob/master/Dockerfile) I wrote for this is incredibly simple. Because the website is a static site, the running container doesn't need any fancy additional runtime, just NGINX, making the container tiny! To help with this, the container is split into 2 stages:
|
[The container](https://github.com/RealOrangeOne/theorangeone.net/blob/master/Dockerfile) I wrote for this is incredibly simple. Because the website is a static site, the running container doesn't need any fancy additional runtime, just NGINX, making the container tiny! To help with this, the container is split into two stages:
|
||||||
|
|
||||||
Stage 1 is based off the nodejs container, where it installs Hugo, installs the production node dependencies, and runs the same custom bash script to build the site into the `public/` directory.
|
Stage one is based off the nodejs container, where it installs Hugo, installs the production node dependencies, and runs the same custom bash script to build the site into the `public/` directory.
|
||||||
|
|
||||||
Stage 2 uses a completely different container as the base, `nginx:latest-alpine`. This ensures the runtime is as minimal as possible. Stage 2 copies the `public/` directory from stage 1 into the server root, and installs a [custom NGINX config](https://github.com/RealOrangeOne/theorangeone.net/blob/master/nginx.conf). This custom config adds a few additional headers, recommended by [securityheaders.io](https://securityheaders.com/), enables `X-Forwarded-For`, and sets up logging to be used by a [GoAccess container for analytics]({{< relref "goaccess-analytics" >}}).
|
Stage two uses a completely different container as the base, `nginx:latest-alpine`. This ensures the runtime is as minimal as possible. Stage two copies the `public/` directory from stage one into the server root, and installs a [custom NGINX config](https://github.com/RealOrangeOne/theorangeone.net/blob/master/nginx.conf). This custom config adds a few additional headers, recommended by [securityheaders.io](https://securityheaders.com/), enables `X-Forwarded-For`, and sets up logging to be used by a [GoAccess container for analytics]({{< relref "goaccess-analytics" >}}).
|
||||||
|
|
||||||
## Deployment
|
## Deployment
|
||||||
|
|
||||||
This container is built using GitHub actions, automatically on push, and then uploaded to GitHubs package registry. A [docker-compose configuration](https://github.com/RealOrangeOne/infrastructure/blob/master/ansible/roles/docker/files/theorangeone.net/docker-compose.yml) is pre-installed on my server, pointed at this container, and with the necessary Traefik rules to route traffic correctly.
|
This container is built using GitHub actions, automatically on push, and then uploaded to GitHubs package registry. A [docker-compose configuration](https://github.com/RealOrangeOne/infrastructure/blob/master/ansible/roles/docker/files/theorangeone.net/docker-compose.yml) is pre-installed on my server, pointed at this container, and with the necessary Traefik rules to route traffic correctly.
|
||||||
|
|
||||||
To maintain auto-deployment functionality, something I find really important, I run [watchtower](https://containrrr.github.io/watchtower/). Watchtower polls the upstream of all containers I depend on, and when there's changes, automatically pulls and restarts them. The poll interval is 5 minutes, so it's a slower update than Netlify, but for my needs it's fine. Generally this is ill-advised as it can cause containers to update unexpectedly, but I pin containers properly, so i'm not worried.
|
To maintain auto-deployment functionality, something I find really important, I run [watchtower](https://containrrr.github.io/watchtower/). Watchtower polls the upstream of all containers I depend on, and when there's changes, automatically pulls and restarts them. The poll interval is five minutes, so it's a slower update than Netlify, but for my needs it's fine. Generally this is ill-advised as it can cause containers to update unexpectedly, but I pin containers properly, so i'm not worried.
|
||||||
|
|
||||||
## Success?
|
## Success?
|
||||||
|
|
||||||
|
|
|
@ -6,11 +6,11 @@ subtitle: Just don't be a dick - It's not that difficult!
|
||||||
|
|
||||||
Spoiling movies is something which has plagued people since forever. If something dramatic happens, of course people don't want to find out by just being told, they want to watch and experience it for themselves. Unfortunately, it seems many people take pride and pleasure in spoiling films for people.
|
Spoiling movies is something which has plagued people since forever. If something dramatic happens, of course people don't want to find out by just being told, they want to watch and experience it for themselves. Unfortunately, it seems many people take pride and pleasure in spoiling films for people.
|
||||||
|
|
||||||
In the last 2 weeks, we've had both Season 8 of Game of Thrones, and Avengers endgame released. Both of which are long-awaited finales to large franchises, and all contain story points which should not be spoiled. I've never quite been able to understand how it's so difficult to not talk about spoilers, whether this be on the internet, in a professional environment, or even down the pub. No matter where you are, you're going to bump into people who won't have seen it yet, and don't appreciate having to hear you talk about it.
|
In the last two weeks, we've had both Season eight of Game of Thrones, and Avengers endgame released. Both of which are long-awaited finales to large franchises, and all contain story points which should not be spoiled. I've never quite been able to understand how it's so difficult to not talk about spoilers, whether this be on the internet, in a professional environment, or even down the pub. No matter where you are, you're going to bump into people who won't have seen it yet, and don't appreciate having to hear you talk about it.
|
||||||
|
|
||||||
## Cardinal Rules
|
## Cardinal Rules
|
||||||
|
|
||||||
There's 2 really simply rules when it comes to spoilers:
|
There's two really simply rules when it comes to spoilers:
|
||||||
|
|
||||||
1. If you've seen a film with a plot point which could be considered a plot spoiler, be careful where you talk about it. Be careful of anyone in earshot, and don't have conversations in public channels.
|
1. If you've seen a film with a plot point which could be considered a plot spoiler, be careful where you talk about it. Be careful of anyone in earshot, and don't have conversations in public channels.
|
||||||
2. If you simply _have_ to talk about something, check that those around either don't care, have already seen it, or are far enough away they can't hear you
|
2. If you simply _have_ to talk about something, check that those around either don't care, have already seen it, or are far enough away they can't hear you
|
||||||
|
|
|
@ -13,7 +13,7 @@ This year marks the 3rd year of my pattern for publishing a "My Stack" post, not
|
||||||
|
|
||||||
For the last couple years, I've been an avid [Antergos](https://web.archive.org/web/20190903082315/https://antergos.com/) user, but May of this year saw [the project end](https://web.archive.org/web/20190809064653/https://antergos.com/blog/antergos-linux-project-ends), forcing me to move. With all my [dotfiles]({{< relref "dotfiles" >}}) configured for an arch-based base, I had little choice than moving to Arch. [Manjaro](https://manjaro.org/) also looked promising, but I'd wanted to move to Vanilla [Arch](https://www.archlinux.org/) for a while, so this felt like as good of a time as any.
|
For the last couple years, I've been an avid [Antergos](https://web.archive.org/web/20190903082315/https://antergos.com/) user, but May of this year saw [the project end](https://web.archive.org/web/20190809064653/https://antergos.com/blog/antergos-linux-project-ends), forcing me to move. With all my [dotfiles]({{< relref "dotfiles" >}}) configured for an arch-based base, I had little choice than moving to Arch. [Manjaro](https://manjaro.org/) also looked promising, but I'd wanted to move to Vanilla [Arch](https://www.archlinux.org/) for a while, so this felt like as good of a time as any.
|
||||||
|
|
||||||
7 months later, I've only hard migrated 3 machines, the rest still run Antergos, and they still run fine. The Antergos repos don't exist any more, but Antergos was really just an installer for vanilla arch with an extra repo, so the fact everything still _just works_ doesn't surprise me.
|
7 months later, I've only hard migrated three machines, the rest still run Antergos, and they still run fine. The Antergos repos don't exist any more, but Antergos was really just an installer for vanilla arch with an extra repo, so the fact everything still _just works_ doesn't surprise me.
|
||||||
|
|
||||||
|
|
||||||
## Desktop Environment
|
## Desktop Environment
|
||||||
|
@ -24,7 +24,7 @@ I'm still an i3 user. I recently [tried using macOS]({{< relref "macos-review" >
|
||||||
|
|
||||||
My editor situation also hasn't changed much in the last year. I still use [VSCode](https://code.visualstudio.com/), although the config has been slightly thinned out so remove extensions I don't use. I recently tried switching back to [IntelliJ](https://www.jetbrains.com/idea/), for the far superior intellisense, but it just didn't feel right, and felt incredibly heavy, not to mention the lack of automatable configuration.
|
My editor situation also hasn't changed much in the last year. I still use [VSCode](https://code.visualstudio.com/), although the config has been slightly thinned out so remove extensions I don't use. I recently tried switching back to [IntelliJ](https://www.jetbrains.com/idea/), for the far superior intellisense, but it just didn't feel right, and felt incredibly heavy, not to mention the lack of automatable configuration.
|
||||||
|
|
||||||
Last year I used [GhostWriter](https://github.com/wereturtle/ghostwriter/) for my markdown editing, but recently I transitioned that into VSCode so I don't need to remember 2 sets of keyboard shortcuts. The fancy WYSIWIG formatting from GhostWriter wasn't a benefit to me, but it's still my recommended markdown editor.
|
Last year I used [GhostWriter](https://github.com/wereturtle/ghostwriter/) for my markdown editing, but recently I transitioned that into VSCode so I don't need to remember two sets of keyboard shortcuts. The fancy WYSIWIG formatting from GhostWriter wasn't a benefit to me, but it's still my recommended markdown editor.
|
||||||
|
|
||||||
[Vim](https://www.vim.org/) is still my terminal editor of choice, but I am looking for something simpler. Some friends often preach [Nano](https://www.nano-editor.org/), which can apparently do many of the editing features Vim has, but the muscle memory is quite hard to get rid of. My [dotfiles]({{< relref "dotfiles" >}}) currently sync a custom Vim configuration, which much like my VSCode configuration, I've also thinned out, but I think there's more thinning to do.
|
[Vim](https://www.vim.org/) is still my terminal editor of choice, but I am looking for something simpler. Some friends often preach [Nano](https://www.nano-editor.org/), which can apparently do many of the editing features Vim has, but the muscle memory is quite hard to get rid of. My [dotfiles]({{< relref "dotfiles" >}}) currently sync a custom Vim configuration, which much like my VSCode configuration, I've also thinned out, but I think there's more thinning to do.
|
||||||
|
|
||||||
|
@ -78,7 +78,7 @@ As a client, I still quite like [Thunderbird](https://www.thunderbird.net/). I t
|
||||||
|
|
||||||
## RSS
|
## RSS
|
||||||
|
|
||||||
For the last 2 or so years now, I've been a heavy RSS user. I've fully replaced YouTube subscriptions with it, because the subscription management is famously garbage.
|
For the last two or so years now, I've been a heavy RSS user. I've fully replaced YouTube subscriptions with it, because the subscription management is famously garbage.
|
||||||
|
|
||||||
As an aggregator, I use [tt-rss](https://tt-rss.org/). [Last year]({{< relref "my-stack-2018" >}}) I said the UI was hard to get to grips with, but after spending more and more time with [FreshRSS](https://www.freshrss.org/), their UI got on my nerves even more.
|
As an aggregator, I use [tt-rss](https://tt-rss.org/). [Last year]({{< relref "my-stack-2018" >}}) I said the UI was hard to get to grips with, but after spending more and more time with [FreshRSS](https://www.freshrss.org/), their UI got on my nerves even more.
|
||||||
|
|
||||||
|
|
|
@ -4,9 +4,9 @@ date: 2019-04-27
|
||||||
tags: [programming]
|
tags: [programming]
|
||||||
---
|
---
|
||||||
|
|
||||||
Object-Oriented Programming (OOP) teaches that classes can have 2 kinds of attributes: Instance and Static. Instance variables are attached to a specific instance of the class, and each has separate memory locations. Static variables are tied to the class itself, and are shared between instances.
|
Object-Oriented Programming (OOP) teaches that classes can have two kinds of attributes: Instance and Static. Instance variables are attached to a specific instance of the class, and each has separate memory locations. Static variables are tied to the class itself, and are shared between instances.
|
||||||
|
|
||||||
The difference between the 2 can be seen clearly in OOP-purist languages like Java. `static` denotes that the variable is static and attached to the class directly.
|
The difference between the two can be seen clearly in OOP-purist languages like Java. `static` denotes that the variable is static and attached to the class directly.
|
||||||
|
|
||||||
```java
|
```java
|
||||||
public class A {
|
public class A {
|
||||||
|
@ -91,7 +91,7 @@ If it were overriding the `'items'` list rather than appending to it, the issue
|
||||||
|
|
||||||
## The solution
|
## The solution
|
||||||
|
|
||||||
There's 2 key ways of fixing the above code: either do OOP properly (in Python), or stop storing things at the object level entirely. I personally lean much more towards the latter, although it may involve a larger refactor.
|
There's two key ways of fixing the above code: either do OOP properly (in Python), or stop storing things at the object level entirely. I personally lean much more towards the latter, although it may involve a larger refactor.
|
||||||
|
|
||||||
```python
|
```python
|
||||||
|
|
||||||
|
@ -117,4 +117,4 @@ Both of these solve the issue by recreating the `'items'` list for each instance
|
||||||
|
|
||||||
## The takeaway
|
## The takeaway
|
||||||
|
|
||||||
If there's 1 thing to take from this, it's not to store things at the object level unless you really have to. Fetching from an API likely doesn't need to store the responses themselves on the instance, and definitely doesn't statically. Defining variables on the class and in the constructor do different things in Python vs other languages.
|
If there's one thing to take from this, it's not to store things at the object level unless you really have to. Fetching from an API likely doesn't need to store the responses themselves on the instance, and definitely doesn't statically. Defining variables on the class and in the constructor do different things in Python vs other languages.
|
||||||
|
|
|
@ -8,7 +8,7 @@ image: https://docs.traefik.io/assets/img/traefik-architecture.png
|
||||||
|
|
||||||
## Basic concepts
|
## Basic concepts
|
||||||
|
|
||||||
Traefik has 4 fundamental concepts: Entrypoints, routers, middleware and services. In that order.
|
Traefik has four fundamental concepts: Entrypoints, routers, middleware and services. In that order.
|
||||||
|
|
||||||
[Entrypoints](https://docs.traefik.io/routing/entrypoints/) are the ports Traefik listens for traffic on. Generally you'd want one for port 80 and another for 443.
|
[Entrypoints](https://docs.traefik.io/routing/entrypoints/) are the ports Traefik listens for traffic on. Generally you'd want one for port 80 and another for 443.
|
||||||
|
|
||||||
|
@ -151,7 +151,7 @@ And now, all traffic which hits our `web` endpoint will be immediately redirecte
|
||||||
|
|
||||||
So, what does a fully configured traefik setup look like? I'm glad you asked!
|
So, what does a fully configured traefik setup look like? I'm glad you asked!
|
||||||
|
|
||||||
First, you'll need to setup and install traefik, which can be done with a very simple docker-compose file, as shown above. Your default configuration will need to define at least 1 entrypoint.
|
First, you'll need to setup and install traefik, which can be done with a very simple docker-compose file, as shown above. Your default configuration will need to define at least one entrypoint.
|
||||||
|
|
||||||
Once you already have traefik installed and setup, adding services is very simple:
|
Once you already have traefik installed and setup, adding services is very simple:
|
||||||
|
|
||||||
|
@ -190,7 +190,7 @@ To add more applications, just start more compose files with more configuration.
|
||||||
|
|
||||||
## Should you use Traefik?
|
## Should you use Traefik?
|
||||||
|
|
||||||
This is a more difficult question than it may seem. Personally I'm super happy I migrated from Nginx to traefik, and I know plenty of others who feel the same. If you're trying to manage a number of different docker containers on 1 machine, then traefik is something worth looking into.
|
This is a more difficult question than it may seem. Personally I'm super happy I migrated from Nginx to traefik, and I know plenty of others who feel the same. If you're trying to manage a number of different docker containers on one machine, then traefik is something worth looking into.
|
||||||
|
|
||||||
However, if you've just got a couple services, and you're comfortable with Nginx, why rock the boat? Both traefik and nginx are reverse proxies, and they're both really good, you're not going to see performance, security, or really simplicity gains by switching. With that said if you're using docker, it's worth a look into anyway.
|
However, if you've just got a couple services, and you're comfortable with Nginx, why rock the boat? Both traefik and nginx are reverse proxies, and they're both really good, you're not going to see performance, security, or really simplicity gains by switching. With that said if you're using docker, it's worth a look into anyway.
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@ C-->D
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
As with any other VPN network, you'll need 2 devices, a server and a client
|
As with any other VPN network, you'll need two devices, a server and a client
|
||||||
|
|
||||||
### VPS
|
### VPS
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@ Do you wish to login to the Admin UI as "openvpn"?
|
||||||
> Press ENTER for default [yes]: yes
|
> Press ENTER for default [yes]: yes
|
||||||
```
|
```
|
||||||
|
|
||||||
OpenVPN Access Server is free for 2 concurrent users. For this, we only need, so no need to enter a license key.
|
OpenVPN Access Server is free for two concurrent users. For this, we only need, so no need to enter a license key.
|
||||||
|
|
||||||
Once the script has finished, you'll need to set the password for the builtin user. Run `sudo passwd openvpn` to do this. Open the _"Admin UI"_ URL displayed after the init script. It's probably `https://<ip>:943/admin`. Here, you can login as the `openvpn` user.
|
Once the script has finished, you'll need to set the password for the builtin user. Run `sudo passwd openvpn` to do this. Open the _"Admin UI"_ URL displayed after the init script. It's probably `https://<ip>:943/admin`. Here, you can login as the `openvpn` user.
|
||||||
|
|
||||||
|
@ -88,7 +88,7 @@ Once logged in, click _"User Permissions"_ in the sidebar, and create a new user
|
||||||
|
|
||||||
### Setting up the VPN user
|
### Setting up the VPN user
|
||||||
|
|
||||||
The new VPN user needs to be told to allow traffic to flow to other devices on its network. To do this, we need to enable a feature called _"VPN Gateway"_. Under the user settings, switch the related radio button to _Yes_, and enter the subnets you want to be accessible. These should be 1 per line, and in the format `192.168.1.0/24`. You will also need to enable access from _"all server side private subnets"_ and _"all other VPN clients"_.
|
The new VPN user needs to be told to allow traffic to flow to other devices on its network. To do this, we need to enable a feature called _"VPN Gateway"_. Under the user settings, switch the related radio button to _Yes_, and enter the subnets you want to be accessible. These should be one per line, and in the format `192.168.1.0/24`. You will also need to enable access from _"all server side private subnets"_ and _"all other VPN clients"_.
|
||||||
|
|
||||||
{{< resource src="user-settings.png" >}}
|
{{< resource src="user-settings.png" >}}
|
||||||
Make sure your user settings look roughly like this.
|
Make sure your user settings look roughly like this.
|
||||||
|
|
|
@ -4,7 +4,7 @@ date: 2017-11-13
|
||||||
image: resource:new-site-screenshot.png
|
image: resource:new-site-screenshot.png
|
||||||
---
|
---
|
||||||
|
|
||||||
I've had a website for around 4 years now, starting with a python CGI-based site hosted at [1&1](https://www.1and1.co.uk/), and evolving into it's current form, powered by [Hugo](https://gohugo.io/).
|
I've had a website for around four years now, starting with a python CGI-based site hosted at [1&1](https://www.1and1.co.uk/), and evolving into it's current form, powered by [Hugo](https://gohugo.io/).
|
||||||
|
|
||||||
Although I'm a web developer, I'm very far from a designer. I really can't design anything!
|
Although I'm a web developer, I'm very far from a designer. I really can't design anything!
|
||||||
|
|
||||||
|
@ -17,6 +17,6 @@ After deciding to do yet another redesign, I had an epiphany. Rather than using
|
||||||
Making the design this simple means there's very little to go wrong. If the whole site looks so simple, it's very hard for it to look quite so bad.
|
Making the design this simple means there's very little to go wrong. If the whole site looks so simple, it's very hard for it to look quite so bad.
|
||||||
|
|
||||||
## Implementation
|
## Implementation
|
||||||
I implemented it in just over 2 weeks, in a [single PR](https://github.com/RealOrangeOne/theorangeone.net/pull/1). In this refactor, I also fixed many things I didn't like about my sites build process. I even installed a [compressor](https://github.com/gschier/speedpack) for deployment.
|
I implemented it in just over two weeks, in a [single PR](https://github.com/RealOrangeOne/theorangeone.net/pull/1). In this refactor, I also fixed many things I didn't like about my sites build process. I even installed a [compressor](https://github.com/gschier/speedpack) for deployment.
|
||||||
|
|
||||||
Overall I'm really happy how the rewrite looks, It's far nicer and more original than my previous sites. Now, to push it live!
|
Overall I'm really happy how the rewrite looks, It's far nicer and more original than my previous sites. Now, to push it live!
|
||||||
|
|
|
@ -6,7 +6,7 @@ date: 2020-03-06
|
||||||
|
|
||||||
## What is Wireguard?
|
## What is Wireguard?
|
||||||
|
|
||||||
The website defines it as "... extremely simple yet fast and modern VPN that utilizes state-of-the-art cryptography.". Which basically means it's a VPN, but sane. The point of a VPN is to allow 2 machines to talk to eachother, no matter how the network inbetween is setup.
|
The website defines it as "... extremely simple yet fast and modern VPN that utilizes state-of-the-art cryptography.". Which basically means it's a VPN, but sane. The point of a VPN is to allow two machines to talk to eachother, no matter how the network inbetween is setup.
|
||||||
|
|
||||||
## Modern Features
|
## Modern Features
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ Wireguard has a lot of nice, modern features.
|
||||||
|
|
||||||
Roaming, If I shut my laptop, go home, and open it again, the tunnel will be in the same state: just fine! None of this weird messed up state issues where you have to disconnect and reconnect.
|
Roaming, If I shut my laptop, go home, and open it again, the tunnel will be in the same state: just fine! None of this weird messed up state issues where you have to disconnect and reconnect.
|
||||||
|
|
||||||
Configuration is also incredibly simple. There's just 1 file of configuration, none of this multiple file fun like OpenVPN. Just a single ini file for the server, and a single, very similar, ini file for the client.
|
Configuration is also incredibly simple. There's just one file of configuration, none of this multiple file fun like OpenVPN. Just a single ini file for the server, and a single, very similar, ini file for the client.
|
||||||
|
|
||||||
Wireguard's authentication model is incredibly simple. The client and server share public keys, and add them to their config files. If you've ever provisioned SSH keys, you'll feel right at home!
|
Wireguard's authentication model is incredibly simple. The client and server share public keys, and add them to their config files. If you've ever provisioned SSH keys, you'll feel right at home!
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ Wireguard is incredibly fast. Take these benchmarks from the Wireguard website,
|
||||||
Wireguard benchmarks. [src](https://www.Wireguard.com/performance/#results)
|
Wireguard benchmarks. [src](https://www.Wireguard.com/performance/#results)
|
||||||
{{< /resource >}}
|
{{< /resource >}}
|
||||||
|
|
||||||
Not only is Wireguard significantly faster than OpenVPN, and sligtly faster still than IPSec, there's an important extra bit of detail. The Wireguard version was the only one not maxing out the CPU, meaning whatever's limitting Wireguard's score, it's not Wireguard itself, it's likely something far more fundemental like networking overhead, seeing as 1011mb is pretty close to 1 gigabit.
|
Not only is Wireguard significantly faster than OpenVPN, and sligtly faster still than IPSec, there's an important extra bit of detail. The Wireguard version was the only one not maxing out the CPU, meaning whatever's limitting Wireguard's score, it's not Wireguard itself, it's likely something far more fundemental like networking overhead, seeing as 1011mb is pretty close to one gigabit.
|
||||||
|
|
||||||
What's yet more scary impressive is this [quote](https://www.Wireguard.com/performance/#performance-roadmap):
|
What's yet more scary impressive is this [quote](https://www.Wireguard.com/performance/#performance-roadmap):
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ Wireguard is taking the VPN world by storm, coming very close to the current cha
|
||||||
|
|
||||||
https://www.wireguard.com/
|
https://www.wireguard.com/
|
||||||
|
|
||||||
Wireguard is not only lighter weight than OpenVPN, it's simpler, smaller, and most importantly does less. The final point may to some seem like a bad thing, but is actually great! The Unix Philosophy defines that tools should do 1 thing, and do it well. Wireguard simply creates networks and tunnels, no funky networking, no custom authentication, no complexity.
|
Wireguard is not only lighter weight than OpenVPN, it's simpler, smaller, and most importantly does less. The final point may to some seem like a bad thing, but is actually great! The Unix Philosophy defines that tools should do one thing, and do it well. Wireguard simply creates networks and tunnels, no funky networking, no custom authentication, no complexity.
|
||||||
|
|
||||||
|
|
||||||
## Getting started with Wireguard
|
## Getting started with Wireguard
|
||||||
|
@ -38,7 +38,7 @@ Wireguard comes with commands to generate the key-pairs securely:
|
||||||
wg genkey | tee privatekey | wg pubkey > publickey
|
wg genkey | tee privatekey | wg pubkey > publickey
|
||||||
```
|
```
|
||||||
|
|
||||||
This creates 2 files, `publickey` and `privatekey` which contain, well, the public and private keys. For security reasons, you should generate the keys on the device which requires the private key, rather than generating them all on the server, and distributing the private key.
|
This creates two files, `publickey` and `privatekey` which contain, well, the public and private keys. For security reasons, you should generate the keys on the device which requires the private key, rather than generating them all on the server, and distributing the private key.
|
||||||
|
|
||||||
### Configuration
|
### Configuration
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@ PrivateKey = <server privatekey> # The servers private key
|
||||||
ListenPort = 51820 # The port for wireguard to listen on (51820 is the standard)
|
ListenPort = 51820 # The port for wireguard to listen on (51820 is the standard)
|
||||||
|
|
||||||
|
|
||||||
# Specify 1 "Peer" block for each connecting device
|
# Specify one "Peer" block for each connecting device
|
||||||
[Peer]
|
[Peer]
|
||||||
PublicKey = <client publickey> # The clients public key
|
PublicKey = <client publickey> # The clients public key
|
||||||
AllowedIPs = 10.1.10.2/32 # The IP and mask the client should be assigned
|
AllowedIPs = 10.1.10.2/32 # The IP and mask the client should be assigned
|
||||||
|
@ -99,6 +99,6 @@ To connect a client, you can also run `wg-quick up <interface>`, and again, you'
|
||||||
|
|
||||||
That's it!
|
That's it!
|
||||||
|
|
||||||
There's now an encrypted tunnel setup between your 2 machines, which can be used to send any kind of traffic over, whether it be web traffic, media streaming, or email (if you're reading this guide and thinking about using the tunnel for email, please don't!).
|
There's now an encrypted tunnel setup between your two machines, which can be used to send any kind of traffic over, whether it be web traffic, media streaming, or email (if you're reading this guide and thinking about using the tunnel for email, please don't!).
|
||||||
|
|
||||||
If your needs are simply to forward traffic via another computer / network, or connect devices to the network of another, look past OpenVPN and give Wireguard a shot!
|
If your needs are simply to forward traffic via another computer / network, or connect devices to the network of another, look past OpenVPN and give Wireguard a shot!
|
||||||
|
|
|
@ -8,6 +8,6 @@ Attack on Blocks is a space invaders style game I wrote for my IT coursework, fo
|
||||||
I decided to write the game in Python, seeing as there were other people in the college that could help me bug report and test features, and because it was already installed on the college computers. I used PyGame for the game engine, because it's really simple to use, and there is a lot of support and documentation online.
|
I decided to write the game in Python, seeing as there were other people in the college that could help me bug report and test features, and because it was already installed on the college computers. I used PyGame for the game engine, because it's really simple to use, and there is a lot of support and documentation online.
|
||||||
|
|
||||||
## Easter Eggs
|
## Easter Eggs
|
||||||
One of the key features of this (and unfortunately the part I spent the most time on), is the easter eggs. There are a few dotted around the game, which make the game either much easier, or way more fun! At the moment, there are 3 main easter eggs, the first enabling the other 2. If you would like to know what they are, click the button below. If not, pay the game and try and find them, or search through the source to find them (it's not too hard through the source).
|
One of the key features of this (and unfortunately the part I spent the most time on), is the easter eggs. There are a few dotted around the game, which make the game either much easier, or way more fun! At the moment, there are three main easter eggs, the first enabling the other two. If you would like to know what they are, click the button below. If not, pay the game and try and find them, or search through the source to find them (it's not too hard through the source).
|
||||||
|
|
||||||
As you will see (If and when you find the easter eggs), most of them are completely useless, and completely unrelated to the game or anything else. The main reason they were put in was because I'm friends with people that pester to the point it's just easier to give in, hence they are really rather odd!
|
As you will see (If and when you find the easter eggs), most of them are completely useless, and completely unrelated to the game or anything else. The main reason they were put in was because I'm friends with people that pester to the point it's just easier to give in, hence they are really rather odd!
|
||||||
|
|
|
@ -12,7 +12,7 @@ If you're using scripts hosted by yourself, then SRI can help prevent against ma
|
||||||
|
|
||||||
## Using SRI with Django
|
## Using SRI with Django
|
||||||
|
|
||||||
SRI has been around for a while, as has Django, but no one has put the 2 together it seems. That's where [`django-sri`](https://github.com/{{< param "repo" >}}/) comes in.
|
SRI has been around for a while, as has Django, but no one has put the two together it seems. That's where [`django-sri`](https://github.com/{{< param "repo" >}}/) comes in.
|
||||||
|
|
||||||
By installing and configuring it correctly, you're given a new `sri_static` template tag, which outputs a fully formed `script` or `link` tag, with the required integrity checks setup.
|
By installing and configuring it correctly, you're given a new `sri_static` template tag, which outputs a fully formed `script` or `link` tag, with the required integrity checks setup.
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ Hugo is my static site generator of choice, it's powering [this website](https:/
|
||||||
If we combine revealjs and a static site generator, we get many benefits. Besides the obvious fact we get to write our content as markdown rather than raw HTML (revealjs does natively support this, but conversion is done in the browser), we also get the ability to use the niceties they offer to make content development easier.
|
If we combine revealjs and a static site generator, we get many benefits. Besides the obvious fact we get to write our content as markdown rather than raw HTML (revealjs does natively support this, but conversion is done in the browser), we also get the ability to use the niceties they offer to make content development easier.
|
||||||
|
|
||||||
## `hugo-theme-revealjs`
|
## `hugo-theme-revealjs`
|
||||||
`hugo-theme-revealjs` is a theme for Hugo which combines the 2: a powerful static site generator, with a powerful presentation framework. The theme makes writing content east, especially for those who like content organised. Each slide is a separate markdown file, which can be grouped into sections to form the vertical slide groups Reveal is famous for. All settings and configuration options for Reveal are accessible through this theme, in an attempt to make it versatile and usable by all people.
|
`hugo-theme-revealjs` is a theme for Hugo which combines the two: a powerful static site generator, with a powerful presentation framework. The theme makes writing content east, especially for those who like content organised. Each slide is a separate markdown file, which can be grouped into sections to form the vertical slide groups Reveal is famous for. All settings and configuration options for Reveal are accessible through this theme, in an attempt to make it versatile and usable by all people.
|
||||||
|
|
||||||
The source for the theme is on [GitHub](https://github.com/RealOrangeOne/hugo-theme-revealjs), and can be [installed](https://gohugo.io/themes/installing-and-using-themes/) as if it were any other theme.
|
The source for the theme is on [GitHub](https://github.com/RealOrangeOne/hugo-theme-revealjs), and can be [installed](https://gohugo.io/themes/installing-and-using-themes/) as if it were any other theme.
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue