Content dump and hide apprentice docs for now...

This commit is contained in:
Sivert V. Sæther 2022-07-04 12:15:48 +00:00
parent 9d95802629
commit 193b7324f7
41 changed files with 758 additions and 51 deletions

View File

@ -0,0 +1,135 @@
[defaults]
roles_path = ~/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles
library = ~/.ansible/plugins/modules:/usr/share/ansible/plugins/modules
inventory = ~/.ansible/hosts,/etc/ansible/hosts
collections_path = ~/.ansible/collections:/usr/share/ansible/collections
# This may be "ignore" or "fail", "warnging" is the default
collections_on_ansible_version_mismatch = warning
collections_scan_sys_path = True
# Very useful, this will issue a warning if you run a command that
# Ansible thinks there is an existing module to do the same job!
command_warnings = True
forks = 42
# The default for gathering is "impicit", meaning Ansible won't cache facts
gathering = smart
gather_timeout = 13
# May specify "paramiko", "ssh" or "smart" for choosing based of OS and ssh versions
transport = smart
use_persistent_connections = True
private_key_file = ~/.ssh/id_rsa
pipelining = ANSIBLE_PIPELINING
# Task timeout, 0 = no timeout
task_timeout = 0
# Connection timeout
timeout = 7
# Run plays as fast as possible
strategy = free
# This gives better performance at the expense of CPU load,
# so I guess you'd want it low on your workstation or laptop,
# but higher on like an Ansible tower or similar automation setup using Ansible
internal_poll_interval = 0.000001
poll_interval = 3
system_tmpdirs = /tmp, /var/tmp
remote_tmp = ~/.ansible/tmp
local_tmp = ~/.ansible/tmp
jinja2_native_warning = True
jinja2_native = True
# This one is only really useful to make sure no secrets are logged on servers
# when running Ansible tower or other automation systems using Ansible
no_log = False
# Logging is disabled on the client if "log_path" is empty
log_path =
# Target hosts logging facility
syslog_facility = LOG_USER
no_target_syslog = False
# Must be one from python [zipfile](https://docs.python.org/3/library/zipfile.html) built-in library that is supported
# on both the client and the target servers Ansible is going to run on, ZIP_DEFLATED is the default
module_compression = ZIP_LZMA
# ZIP_STORED = no compression
# ZIP_DEFLATED = normal zip, requires zlib python module
# ZIP_BZIP2 = bzip2, requires bz2 python module
# ZIP_LZMA = lzma, requires lzma python module
# Default module to run with the "ansible" command if not -m [module] is specified
module_name = command
# What will null variables in templates show?
null_representation =
# Let's make some errors warnings instead
invalid_task_attribute_failed = False
error_on_missing_handler = False
string_conversion_action = warn
# The same as the -v command line arg
verbosity = 0
# Extra output goodness!~
show_task_path_on_failure = True
display_args_to_stdout = True
display_skipped_hosts = True
show_per_host_start = True
check_mode_markers = True
show_custom_stats = True
display_ok_hosts = True
# This may be useful
retry_files_enabled = False
yaml_valid_extensions = .yml, .yaml, .json
display_failed_stderr = True
[persistent_connection]
command_timeout = 42
connect_retry_timeout = 7
connect_timeout = 60
[connection]
# This only works if your become supports not using a tty,
# but gives "significant performance improvement when enabled."
pipelining = True
# Eye-candy!
[colors]
changed = bright yellow
console_prompt = white
debug = gray
deprecate = purple
diff_add = green
diff_lines = cyan
diff_remove = red
error = red
highlight = white
ok = green
skip = cyan
unreachable = bright red
verbose = blue
warn = bright purple
[selinux]
# Enable this if running SELinux
libvirt_lxc_noseclabel = False
# We want this to be empty unless maybe nfs target? it may be a list of filesystems
special_context_filesystems =
[diff]
always = True
context = 3
[inventory]
enable_plugins = host_list, script, auto, yaml, ini, toml
[paramiko_connection]
host_key_auto_add = True

View File

View File

@ -0,0 +1,56 @@
[prod]
lost-islands
[prod:children]
prod_frontend
prod_backend
prod_vpn
prod_db
monitor
backups
misc
[prod_frontend]
hamar
toten
[prod_backend]
lofoten
narvik
[prod_vpn]
bergen
molde
[prod_db]
hangar-22
[monitor]
smokeping.skyid.no
monitoring
[backups]
backup.skyid.no
myrkdalen
[misc]
gulf-of-oman
deploy
[dev:children]
dev_frontend
dev_backend
dev_vpn
dev_db
[dev_frontend]
mercury
[dev_backend]
scrapmetal
[dev_vpn]
dawnbreaker
[dev_db]
propaganda

View File

@ -0,0 +1,67 @@
#!/usr/bin/python3
from json import dumps
inv = {
'prod_frontend': {
'hosts': ['toten', 'hamar']
}, 'prod_backend': {
'hosts': ['lofoten', 'narvik']
}, 'prod_vpn': { # vpn/radius
'hosts': ['bergen', 'molde']
}, 'prod_db': {
'hosts': ['hangar-22']
}, 'prod': {
'hosts': ['lost-islands'], # monitoring and internal DNS
'children': [
'prod_frontend', 'prod_backend', 'misc',
'prod_vpn', 'prod_db', 'backups', 'monitor'
]
},
'misc': {
'hosts': ['gulf-of-oman', 'deploy']
}, 'backups': {
'hosts': ['myrkdalen', 'backup.skyid.no']
}, 'monitor': {
'hosts': ['monitoring', 'smokeping.skyid.no']
},
'dev_frontend': { 'hosts': ['mercury'] },
'dev_backend': { 'hosts': ['scrapmetal'] },
'dev_vpn': { 'hosts': ['dawnbreaker'] },
'dev_db': { 'hosts': ['propaganda'] },
'dev': {
'children': [
'dev_frontend', 'dev_backend', 'dev_vpn', 'dev_db'
]
},
"_meta": {
# since we're not doing hostvars this will make it a whole lot faster
# as Ansible won't have to run this script with --host for each one
"hostvars": {}
}
}
def inventory():
return dumps(inv, indent=2)
def group_vars(host):
for group in inv.values():
if host in group.get('hosts', []):
return dumps(group.get('vars', {}), indent=2)
return '{}'
if __name__ == '__main__':
from argparse import ArgumentParser
argparse = ArgumentParser()
argparse.add_argument(
'-l', '--list', action='store_true',
help='Print the inventory to stdout')
argparse.add_argument(
'-v', '--host', type=str,
help='Print host vars for a specific host')
args = argparse.parse_args()
if args.list:
print(inventory())
elif args.host:
print(group_vars(args.host))
else:
argparse.print_help()

View File

@ -0,0 +1,18 @@
lost-islands
toten
hamar
lofoten
narvik
gulf-of-oman
deploy
bergen
molde
hangar-22
myrkdalen
backup.skyid.no
monitoring
smokeping.skyid.no
mercury
scrapmetal
dawnbreaker
propaganda

View File

@ -0,0 +1,47 @@
all:
children:
prod:
hosts:
lost-islands:
children:
prod_frontend:
hosts:
hamar:
toten:
prod_backend:
hosts:
lofoten:
narvik:
prod_vpn:
hosts:
bergen:
molde:
prod_db:
hosts:
hangar-22:
monitor:
hosts:
smokeping.skyid.no:
monitoring:
backups:
hosts:
backup.skyid.no:
myrkdalen:
misc:
hosts:
gulf-of-oman:
deploy:
dev:
children:
dev_frontend:
hosts:
mercury:
dev_backend:
hosts:
scrapmetal:
dev_vpn:
hosts:
dawnbreaker:
dev_db:
hosts:
propaganda:

View File

@ -0,0 +1,8 @@
class AccessControl:
current_user = None
...
def get_current_user(self):
if self.current_user.deleted is None:
return self.current_user
else:
raise Forbidden

View File

@ -0,0 +1,5 @@
class AccessControl:
current_user = None
...
def get_current_user(self):
return self.current_user

View File

@ -0,0 +1,2 @@
Options +ExecCGI
AddHandler cgi-script .cgi .pl .py .sh .rb

View File

@ -1,6 +1,5 @@
.chroma { .chroma { overflow: auto; color: #ffffff; background-color: #111111; }
min-height: 3.3vh; overflow: auto;
color: #ffffff; background-color: #111111; }
.chroma .lntd { vertical-align: top; padding: 0; margin: 0; border: 0 } .chroma .lntd { vertical-align: top; padding: 0; margin: 0; border: 0 }
.chroma .lntable { border-spacing: 0; padding: 0; margin: 0; border: 0 } .chroma .lntable { border-spacing: 0; padding: 0; margin: 0; border: 0 }
.chroma .hl { background-color: #ffffcc } .chroma .hl { background-color: #ffffcc }

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 361 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 241 KiB

BIN
assets/me.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 388 KiB

View File

@ -1,6 +1,6 @@
--- ---
date: 2022-04-05T18:33:08Z date: 2022-04-05T18:33:08Z
draft: false draft: true
aliases: [] aliases: []
categories: ['apprentice', 'indices', 'meta'] categories: ['apprentice', 'indices', 'meta']
series: ['apprentice'] series: ['apprentice']

View File

@ -2,10 +2,103 @@
date: 2022-06-07T07:15:24Z date: 2022-06-07T07:15:24Z
draft: true draft: true
aliases: [] aliases: []
categories: ['various'] categories: ['documentation']
series: [] series: ['apprentice']
tags: ['various'] tags: ['tools', 'tech']
chroma: true
toc: true toc: true
title: Ansible title: Ansible
description: description: Ansible quickstart guide!
--- ---
Ansible is a cool tool that lets you manage lots of Linux servers and even some other devices.
All with just a bunch of yaml.
Although not necessarily as it supports a nice load of formats for everything.
Yaml being the most common, but "inventories" are usually ini format.
But still you should be able to do everything in json if you really want to.
## Configure ansible.cfg
This is the main Ansible config.
Ansible lets you have global stuff in /etc/ansible or project stuff in the working directory.
Anyway you'll likely want an ansible.cfg with your common global configuration options for Ansible itself.
### Example global ansible.cfg
This example ansibe.cfg lists a collection of the options I think are useful.
You may also generate a file with all options available commented out.
With comments describing them for most of the options by;
{{< highlight sh "lineNos=none" >}}ansible-config init --disabled -t all > ansible.cfg{{< /highlight >}}
{{< highlight cfg >}}{{% asset "apprentice/ansible/ansible.cfg" %}}{{< /highlight >}}
### Example project ansible.cfg
{{< highlight cfg >}}[default]
private_key_file = ~/.ssh/ansible_rsa
remote_user = ansible
inventory = all-machines
[privilege_escalation]
become = yes
{{< /highlight >}}
## Inventory
I think it's super neat that Ansible lets you use several file formats for most things.
Inventories being the one that supports most formats, I'm pretty sure.
As you may just have a text file list, or YAML, INI, TOML and JSON to use host groups.
You may even have scripts that generate the target hosts with groups and everything.
If you opt for the script inventory route that script has to output the inventory in JSON format.
There is also the possibility of creating your own inventory plugin with python.
For the script based inventory you have to support command-line arguments "--list" and "--host <hostname>".
Those have to output the whole inventory in JSON format for "--list".
And the host vars for "--host <hostname>".
### The simplest inventories
These are of course just lists of hosts, they could be in a text file or specified from the command-line as a comma separated list.
Then you've got INI file based inventories, and it quickly may become advanced after that.
Even with the INI based ones you may group hosts together.
Next up is three examples that effectively gives the same inventory.
Although the text file won't give host groups.
#### A text file inventory list
{{< highlight txt >}}{{% asset "apprentice/ansible/inv.txt" %}}{{< /highlight >}}
#### INI inventory
Now host groups come into the picture and the rest of the examples will all give the same inventory.
{{< highlight ini >}}{{% asset "apprentice/ansible/inv.ini" %}}{{< /highlight >}}
### Example YAML inventory
This one will give you the exact inventory as above.
{{< highlight yml >}}{{% asset "apprentice/ansible/inv.yml" %}}{{< /highlight >}}
### Example python inventory script
This one is kinda just stupid as it just json dumps a dict containing the whole inventory.
To do some real magic with this you'd want to make that whole dict generated by code.
Very useful if for some reason your inventory is highly dynamic.
{{< highlight py >}}{{% asset "apprentice/ansible/inv.py" %}}{{< /highlight >}}
## Inventory summary
So the takeaway in my opinion is that INI or TOML based inventories are best.
As the YAML based ones are no fun working with.
JSON is also not optimal to manually work with, but a script generating that JSON may be very useful.
Again if you have the need of a potentially very dynamic inventory.
There is also the inventory parameters, these let you override lots of settings on a per-host basis.
Here is a super simple inventory to test plays/playbooks against a docker container;
{{< highlight ini >}}[docker]
docker-test ansible_connection=docker ansible_user=root ansible_host=ansible
{{< /highlight >}}
You may use that inventory and run plays agains whatever container is named "ansible".
Or change the "ansible_host" parameter to the name of whatever container you'd like to use.
These optional parameters are "ansible_" something.
And you may control everything from connection and
INVENTORY PARAMETERS!

View File

@ -0,0 +1,13 @@
---
date: 2022-06-20T14:11:01Z
draft: true
aliases: []
categories: ['various']
series: []
tags: ['various']
chroma: false
toc: true
title: Azure AD
description: Azure Active Directory basics
---

View File

@ -0,0 +1,13 @@
---
date: 2022-06-20T14:07:02Z
draft: true
aliases: []
categories: ['various']
series: []
tags: ['various']
chroma: false
toc: true
title: cPanel
description: cPanel is a server interface provided by many hosting providers for web based management of the servers by their customers
---

View File

@ -0,0 +1,13 @@
---
date: 2022-06-20T14:10:48Z
draft: true
aliases: []
categories: ['various']
series: []
tags: ['various']
chroma: false
toc: true
title: Debian
description: Systems administration stuff relevant to Debian spesifically
---

View File

@ -0,0 +1,13 @@
---
date: 2022-06-13T08:42:53Z
draft: true
aliases: []
categories: ['various']
series: []
tags: ['various']
chroma: false
toc: true
title: Docker Fix
description: The adventure I went through with fixing a terrible docker-compose local development setup
---

View File

@ -0,0 +1,18 @@
---
date: 2022-06-11T17:33:55Z
draft: true
aliases: []
categories: ['docker']
series: ['apprentice']
tags: ['programming', 'devops', 'docker']
chroma: false
toc: true
title: Docker
description: Introduction to Docker for local development and production deployment ready images.
---
Docker is a super container management system that let's you isolate programs and services running on servers.
This is very useful, both during development and for production deployment.
Because all dependencies may be bundled into the "docker image", and if the program/service is hacked.
The adversary will only have access to the container.
Which with proper configuration

View File

@ -10,4 +10,29 @@ title: My terrible Apprentice experience!
description: Here I'm going to write about my terrible time as an IT apprentice in two different small Norwegian companies. First one does web hosting, second runs Captive Portal services. description: Here I'm going to write about my terrible time as an IT apprentice in two different small Norwegian companies. First one does web hosting, second runs Captive Portal services.
--- ---
To be quite frank I had a pretty terrible time as an apprentice.
With problems all the way.
It would've probably gone by fine if I didn't have any sleeping issues.
But that's whatever, cause still both companies I worked at as an apprentice in, in my opinion.
Should've never even been accepted to have apprentices in the first place.
As in Norway the company needs to be registered, with one guy who is supposed to teach stuff to the apprentices.
And another one whom which the apprentices may go to if any issue in the workplace should appear.
All of this was for sure very lacking in both companies.
And it feels like I was just a normal employee that got payed like :poop:.
## Timeline
In chronological order I got approved at Sircon kinda late, after we were done at school and most of the class already working.
And after finding two security issues and being late three times they fired me after only one and a half month.
Two months on paper, but I couldn't do any real IT work after they gave me a notice of the firing.
As they turned off my computer and removed my access to everything while I was given the talk.
After that I just barely got into some alternative thing at school.
That was kinda nice actually, and I probably should've just gone through with it.
Cause then I'd have my papers after only one year.
Whereas a normal apprenticeship in Norway is two years in almost all fields.
This alternative was also pretty fun.
Because my teacher let me work on whatever, as long as it was IT focused and I documented it.
The reason I still went to SkyLabs after all that is mostly money...
Which also happens to seem like the root of my biggest problems at that company...

View File

@ -0,0 +1,12 @@
---
date: 2022-06-11T13:02:54Z
draft: true
aliases: []
categories: ['apprentice']
series: ['apprentice']
tags: ['apprentice', 'various']
chroma: false
toc: true
title: School
description: My experience in some school apprenticeship alternative
---

View File

@ -7,5 +7,7 @@ series: ['apprentice', 'expose']
tags: ['apprentice', 'expose', 'various'] tags: ['apprentice', 'expose', 'various']
toc: true toc: true
title: Sircon title: Sircon
description: description: My experience as an apprentice working for the hosting company Sircon
--- ---

View File

@ -2,10 +2,10 @@
date: 2022-05-25T09:54:05Z date: 2022-05-25T09:54:05Z
draft: true draft: true
aliases: [] aliases: []
categories: ['various'] categories: ['apprentice', 'expose']
series: [] series: ['apprentice', 'expose']
tags: ['various'] tags: ['apprentice', 'expose', 'various']
toc: true toc: true
title: Skylabs title: Skylabs
description: description: My experience as an apprentice working for the captive portal service company SkyLabs
--- ---

View File

@ -0,0 +1,13 @@
---
date: 2022-06-20T14:10:14Z
draft: true
aliases: []
categories: ['various']
series: []
tags: ['various']
chroma: false
toc: true
title: Flask
description: Introduction to using Python Flask for creating web servers
---

View File

@ -6,6 +6,7 @@ categories: ['various']
series: [] series: []
tags: ['various'] tags: ['various']
toc: true toc: true
title: Freeradius title: FreeRADIUS
description: description: FreeRADIUS basics and some bad production configs I've had to work with
--- ---

View File

@ -13,6 +13,7 @@ docs:
- url: https://handlebarsjs.com/guide/ - url: https://handlebarsjs.com/guide/
name: Handlebars official guide name: Handlebars official guide
--- ---
Handlebars.js is a templating engine like jinja2, but entirely in JavaScript. Handlebars.js is a templating engine like jinja2, but entirely in JavaScript.
Personally I've only found pug templates very nice to work with as I love the minimal syntax. Personally I've only found pug templates very nice to work with as I love the minimal syntax.

View File

@ -7,6 +7,7 @@ series: []
tags: ['various'] tags: ['various']
chroma: false chroma: false
toc: true toc: true
title: Jquery title: jQuery
description: description: The JavaScript library jQuery is often very useful for frontend web development, but it may easily lead to the dreaded "callback hell"
--- ---

View File

@ -7,5 +7,6 @@ series: []
tags: ['various'] tags: ['various']
toc: true toc: true
title: Meraki title: Meraki
description: description: Cisco Meraki basics and captive portal setup
--- ---

View File

@ -8,5 +8,14 @@ tags: ['various']
chroma: false chroma: false
toc: true toc: true
title: Mikrotik title: Mikrotik
description: description: Mikrotik routers has a lot of wierd stuff builtin, here is some of that
--- ---
# Full disk problem
The built-in drive on the boxes may get filled up by hidden files...
There exists an official [fix_space](https://www.mikrotik.com/download/share/fix_space.npk) package, but finding that was a little adventure in itself reading through old forum threads from 2018...
# SkyLabs provisioning/setup problem

View File

@ -0,0 +1,13 @@
---
date: 2022-06-20T14:10:19Z
draft: true
aliases: []
categories: ['various']
series: []
tags: ['various']
chroma: false
toc: true
title: MSAL
description: MSAL the new and cloud/Azure AD only version of the old ADAL, both of these are libraries that Microsoft has implemented in sevral programming languages for Active Directory authenitication built into whatever apps you're programming
---

View File

@ -0,0 +1,13 @@
---
date: 2022-06-20T14:10:33Z
draft: true
aliases: []
categories: ['various']
series: []
tags: ['various']
chroma: false
toc: true
title: PostgreSQL
description: PostgreSQL is a pretty good SQL database server that even implements PL/pgSQL that is like a whole programming language on it's own
---

View File

@ -39,31 +39,16 @@ And the fix for it was super easy!~
We use a custom endpoint decorator, like flasks own @app.route, but we control what happens. We use a custom endpoint decorator, like flasks own @app.route, but we control what happens.
It's here the authentication is implemented, on all requests that go to routes defined with this decorator will run the Access Control controller. It's here the authentication is implemented, on all requests that go to routes defined with this decorator will run the Access Control controller.
Access Control goes through the auth options in it's dunder init function and sets self.current_user to some admin user from the database. Access Control goes through the auth options in its dunder init function and sets self.current_user to some admin user from the database.
To fix the problem I could've made this check specific to the API keys by putting it in the API key controller that also has a user getter function. To fix the problem I could've made this check specific to the API keys by putting it in the API key controller that also has a user getter function.
But I chose to add an if statement to the Access Control user getter, this is called by our endpoint decorator. But I chose to add an if statement to the Access Control user getter, this is called by our endpoint decorator.
So I literally just changed this. So I literally just changed this.
{{< highlight py >}} {{< highlight py >}}{{% asset "apprentice/security/accesscontrol.py" %}}{{< /highlight >}}
class AccessControl:
current_user = None
...
def get_current_user(self):
return self.current_user
{{< /highlight >}}
To that! To that!
{{< highlight py >}} {{< highlight py >}}{{% asset "apprentice/security/accesscontrol-fix.py" %}}{{< /highlight >}}
class AccessControl:
current_user = None
...
def get_current_user(self):
if self.current_user.deleted is None:
return self.current_user
else:
raise Forbidden
{{< /highlight >}}
To fix this issue. To fix this issue.
@ -74,6 +59,12 @@ The HTTP response will be error 500 if it's a Python error.
But if it's one of our own error classes that's been raised. But if it's one of our own error classes that's been raised.
Then an error code, description and status code will be taken from that exception class and sent as the response. Then an error code, description and status code will be taken from that exception class and sent as the response.
There is also the case of the JWT secret key that's wayyy too small.
And not changed since it was introduced in the admin API.
Old keys is a theme on SkyLabs servers.
I'm surprised no one, as far as we know anyway, has broken into the servers yet.
#### Funny #### Funny
Something I find kinda funny is the fact that those exception descriptions are in English, but the admin frontend is entirely in Norwegian only. Something I find kinda funny is the fact that those exception descriptions are in English, but the admin frontend is entirely in Norwegian only.
It's even got a big ass JavaScript file that maps all the error codes to messages. It's even got a big ass JavaScript file that maps all the error codes to messages.
@ -96,14 +87,27 @@ We use Ansible to manage the servers and deploy code updates.
There is an Ansible var file that has a list of user accounts with options for shell and ssh pubkey. There is an Ansible var file that has a list of user accounts with options for shell and ssh pubkey.
That file also has a list of old accounts that should be deleted. That file also has a list of old accounts that should be deleted.
These are per employee users. These are per employee users.
But the intrauser and ansible users have existed since 2016... But the intrauser and Ansible users have existed since 2016...
using the same keys that they were created with. using the same keys that they were created with.
The reason this is such a big threat is the fact that intrauser, ansible and all employee accounts has sudo access without password. The reason this is such a big threat is the fact that the Ansible and all employee accounts has sudo access without password.
The intrauser does actually have a password set, but it may use sudo without password when running rsync.
And the thing is, [gtfobins](https://gtfobins.github.io/) has a privilege escalation exploit for rsync that our servers are vulnerable to.
So check it; these screenshots are from SkyLabs' Ansible git log!~ So check it; these screenshots are from SkyLabs' Ansible git log!~
{{< img src="apprentice/skyid/intrauser-key.png" caption="Me finally updating the key" >}} {{< img src="apprentice/skyid/intrauser-key.png" caption="Me finally updating the key" >}}
And it's even worse... as it turns out the OpenVPN setup also has keys from guess when!
That's right! 2016...
So even if you only got access to the intrauser, it's super easy getting local privilege escalation on the servers.
To be honest I'm quite surprised the servers hasn't been pwnd big time!
As I've in fact proven that any ex-employee that has a copy of our Ansible repo could easily forge OpenVPN client keys and certificates.
And also got full root access over ssh anyway.
Just add a little [Tor](https://torproject.org/) magic on top of that, and you got full access to all the servers without us being able to trace it back...
## Sircon ## Sircon
These guys has a few beefy ass physical servers in their own rack in a supposedly EMP and fire safe room in the basement of their offices. These guys has a few beefy ass physical servers in their own rack in a supposedly EMP and fire safe room in the basement of their offices.
Those physical machines run virtual machines that run WHM/cPanel and whatever PHP app the customer would like. Those physical machines run virtual machines that run WHM/cPanel and whatever PHP app the customer would like.
@ -123,10 +127,7 @@ As they don't allow ssh access and PHP is configured to not allow anything dange
Example .htaccess to run cgi scripts. Example .htaccess to run cgi scripts.
{{< highlight apache >}} {{< highlight apache >}}{{% asset "apprentice/security/htaccess" %}}{{< /highlight >}}
Options +ExecCGI
AddHandler cgi-script .cgi .pl .py .sh .rb
{{< /highlight >}}
The fix for this is the [AllowOverride](https://httpd.apache.org/docs/current/mod/core.html#allowoverride) directive. The fix for this is the [AllowOverride](https://httpd.apache.org/docs/current/mod/core.html#allowoverride) directive.
Just make sure it does not include "FileInfo". Just make sure it does not include "FileInfo".

View File

@ -7,7 +7,7 @@ series: ['apprentice']
tags: ['python'] tags: ['python']
toc: true toc: true
title: SQLAlchemy title: SQLAlchemy
description: description: SQLAlchemy is a so called "Object Relational Mapper" for Python, these ORMs are very useful as you can get IDE support for interacting with the database
--- ---
[SQLAlchemy docs](https://docs.sqlalchemy.org/en/latest/orm/quickstart.html) [SQLAlchemy docs](https://docs.sqlalchemy.org/en/latest/orm/quickstart.html)

View File

@ -0,0 +1,13 @@
---
date: 2022-06-20T14:07:06Z
draft: true
aliases: []
categories: ['various']
series: []
tags: ['various']
chroma: false
toc: true
title: WHM
description: Web Host Manager, this is the secret sauce for many companies that do shared Linux server web hosting with cPanel
---

View File

@ -0,0 +1,13 @@
---
date: 2022-06-20T14:06:54Z
draft: true
aliases: []
categories: ['various']
series: []
tags: ['various']
chroma: false
toc: true
title: WordPress
description: The worlds most popular and whackiest web page Content Management System
---

59
content/cv.en.md Normal file
View File

@ -0,0 +1,59 @@
---
date: 2022-06-19T15:24:00Z
draft: true
aliases: ['Curriculum Vitae']
categories: ['meta']
series: ['me']
tags: ['meta']
toc: true
title: My CV
description: My CV/Curriculum Vitae
---
{{< img src="me.jpg" caption="Me, Sivert V. Sæther" >}}
Hi, I'm Sivert V. Sæther.
I do computer stuff, like programming and Linux server administration.
## Experience
### IT apprentice
#### SkyLabs AS
##### 1. May 2021 - 31. October 2022
SkyLabs provide captive portal services with lots of supported authentication methods.
Here I did lots of programming, administered the servers and even did production code deployments!
#### Sircon Norge AS
##### 21. September 2020 - 19. November 2020
Technical cPanel/WHM support with customers mainly running WordPress.
### Summer jobs
#### Housing Association Janitor
##### Juli 2017 - August 2017, and Juni 2019 - Juli 2019
This was a very good program with good pay where we did various tasks in the area where we lived.
Such as cutting the grass, trimming bushes and painting stuff.
## Education
### Norwegian high school
Heimdal videregående skole 2019 - 2020 /
VG2 IKT-Servicefag (IT program with focus on support)
Byåsen videregående skole 2018 - 2019 /
VG1 Studiespesialisering (higher education prep program)
## Hobbies
I operate several hobby Linux servers, and program cool stuff.
I'm a big Docker fan, running most of the services on those servers in it.
As for programming I'd say I'm definitely most fluent in Python, but I'm a big fan of rust and go.
I also like gaming and parties.
## References
Name - Workplace - phone number
{{< block >}}
Jørgen Kirsebom - IT Luftkrigsskolen (IT Department The Air War School in Trondheim) - [+47 951 49 735](tel:+4795149735)
Knut Eivind Brennhaug - Main teacher IKT-servicefag/IT - [+47 975 15 183](tel:+4797515183)
Kenneth Bjørsvik - SkyLabs AS - [+47 959 37 212](tel:+4795937212)
Nils R. Grotnes - SkyLabs AS - [+47 904 25 862](tel:+4790425862)
{{< /block >}}

21
content/cv.no.md Normal file
View File

@ -0,0 +1,21 @@
---
date: 2022-06-19T15:24:03Z
draft: true
aliases: ['Curriculum Vitae']
categories: ['meta']
series: ['me']
tags: ['meta']
toc: true
title: Min CV
description: Min CV/Curriculum Vitae
tocExtra: |
---
# Referanser
Navn Arbeidsplass telefon nummer
Jørgen Kirsebom - IT Luftkrigsskolen - +47 951 49 735
Knut Eivind Brennhaug - Kontaktlærer fra IKT - +47 975 15 183
Kenneth Bjørsvik - SkyLabs AS - +47 959 37 212

View File

@ -5,6 +5,6 @@
{{ $content := .Inner }} {{ $content := .Inner }}
{{ $in := split .Inner "\n" }} {{ $in := split .Inner "\n" }}
{{ if gt (len $in) 1 }} {{ if gt (len $in) 1 }}
{{ $content = (delimit (after 1 $in) "\n") }} {{ $content = (delimit $in "\n") }}
{{ end }} {{ end }}
{{ transform.Highlight (htmlUnescape $content) (.Get 0) (delimit $opts ",") }} {{ transform.Highlight (htmlUnescape $content) (.Get 0) (delimit $opts ",") }}

View File

@ -0,0 +1,9 @@
<video
width='{{ with.Get 2 }}{{ . }}{{ else }}100%{{ end }}'
height='{{ with .Get 3 }}{{ . }}{{ else }}100%{{ end }}'
{{ with .Get 1 }}{{ . }}{{ else }}controls{{ end }}>
{{ with resources.Get (.Get 0) }}
<source src='{{ .RelPermalink }}' type='{{ .MediaType }}'>
{{ end }}
<b>Your browser does not support the video tag!</b>
</video>