A fast raspberry pi setup. This guide is currently being written.
- Install Alpine Linux on Raspberry Pi guide.
- Configure sshd with mozilla config.
- Configure regular stuff.
- Install #needed-software.
- Configure #ramfs.
- Configure #www.
List of software that you should install (possibly not complete):
- nginx nginx-doc
- git git-doc
- musl-dev libc-dev g++
- gcc gcc-doc make make-doc bmake bmake meson meson-doc samurai samurai-doc
$ apk add nginx ...
- Create the directories
/var/tank/ram
and/var/ram
. - Add ramfs to
/etc/fstab
:
tmpfs /var/ram tmpfs rw,nodev,defaults,size=600M 0 0
- Create the file
/etc/init.d/ramsyncd
, and open it in vim. The contents of/etc/init.d/ramsyncd
should be this:
#!/sbin/openrc-run
supervisor="supervise-daemon"
command=/usr/local/bin/ramsyncd
pidfile=/var/run/ramsyncd
name=$RC_SVCNAME
description="/var/ram sync daemon"
depend() {
need localmount
after bootmisc
before nginx
}
start_pre() {
rsync -rauL --delete /var/tank/ram/ /var/ram > /dev/null
}
stop_post() {
rsync -rauL --delete /var/ram/ /var/tank/ram > /dev/null
}
Now enable and start ramsyncd
:
$ rc-update add ramsyncd boot # Add service to start at boot
$ rc-service ramsyncd start # Start the service
The daemon ramsyncd
will sync /var/tank/ram
and /var/ram
. The daemon syncs
from /var/ram
-> /var/tank/ram
every minute and at shutdown. The daemon
syncs from /var/tank/ram
-> /var/ram
on boot. :)
Start by creating /var/ram/www
, then create a src
folder and a folder with your domain (example.com
).
Your directoy tree should look something like this:
.
├── example.com
└── src
You can now clone the source of your website into the src folder.
/var/ram/www/src $ git clone ...
You can now compile the website source code and cp/symlink it to /var/ram/www/example.com
.
- Delete
/etc/nginx/conf.d
&/etc/nginx/http.d
. - Create
/etc/nginx/snippets/
and write contents to them.
/etc/nginx/snippets/acmeroot.conf
location /.well-known/acme-challenge/ {
root "/var/ram/www/acme";
}
/etc/nginx/snippets/secure-http.conf
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
add_header X-Content-Type-Options "nosniff" always;
# Setup CSP
add_header Content-Security-Policy "default-src 'self' data: 190405.xyz; frame-src 'self'" always;
add_header X-Content-Security=Policy "default-src 'self' data: 190405.xyz; frame-src 'self'" always;
add_header X-WebKit-CSP "default-src 'self' data: 190405.xyz; frame-src 'self'" always;
/etc/nginx/snippets/secure-https.conf
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Strict-Transport-Security "max-age=172800" always;
# Setup CSP
add_header Content-Security-Policy "default-src 'self' data: 190405.xyz; frame-src 'self'" always;
add_header X-Content-Security=Policy "default-src 'self' data: 190405.xyz; frame-src 'self'" always;
add_header X-WebKit-CSP "default-src 'self' data: 190405.xyz; frame-src 'self'" always;
/etc/nginx/snippets/default-cache.conf
etag on;
expires 24h;
/etc/nginx/snippets/no-cache.conf
etag off;
expires off;
add_header Cache-Control 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0';
/etc/nginx/nginx.conf
# /etc/nginx/nginx.conf
worker_processes auto;
user nginx;
pcre_jit on;
error_log /var/log/nginx/error.log warn;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
# ETC
resolver 1.1.1.1 1.0.0.1;
server_tokens off;
client_max_body_size 1m;
sendfile on;
tcp_nopush on;
gzip_vary on;
# SSL
ssl_protocols TLSv1.2 TLSv1.3;
# to generate: openssl dhparam -out /etc/ssl/nginx/dh2048.pem 2048
ssl_dhparam /etc/ssl/nginx/dh2048.pem;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:2m;
ssl_session_timeout 1h;
ssl_session_tickets off;
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
# Specifies the main log format.
log_format main '[$time_local] $remote_addr - $host "$request" '
'$status $remote_user "$http_referer" "$http_user_agent"';
access_log /var/log/nginx/access.log main;
# 190405.xyz
server {
listen 80;
server_name 190405.xyz;
root /var/ram/www/190405.xyz;
autoindex off;
index index.xhtml;
include /etc/nginx/snippets/secure-http.conf;
include /etc/nginx/snippets/acmeroot.conf;
location / {
try_files $uri $uri/ =404;
}
}
# Default server
server {
listen 80 default_server;
server_name _;
root /var/ram/www/default;
autoindex off;
index index.html;
include /etc/nginx/snippets/secure-http.conf;
location / {
try_files $uri $uri/ =404;
}
}
# Git http server
server {
listen 80;
server_name git.190405.xyz;
root /var/ram/www/default;
autoindex on;
include /etc/nginx/snippets/secure-http.conf;
# default location
location / {
# redirect git to @git
# redirect web to @web
error_page 460 = @web;
error_page 461 = @git;
recursive_error_pages on;
if ($http_user_agent ~* git\/.*) {
return 461;
}
location / {
return 460;
}
}
# serve raw git files
location @git {
root /var/ram/www/git;
include /etc/nginx/snippets/no-cache.conf;
client_max_body_size 0;
autoindex on;
try_files $uri $uri/ =404;
}
# serve nicer view (if available)
location @web {
root /var/ram/www/git;
include /etc/nginx/snippets/default-cache.conf;
autoindex on;
try_files $uri $uri/ =404;
}
}
}
Our goal is to have two git folders: one public and one private.
The public folder will be available using http, but the private will only be available using ssh.
Create the directories /var/ram/git
, /var/ram/git/public
and /var/ram/git/private
.
We will use a script for our repository creation and some others for other things.
/var/ram/git/doas.sh
#!/bin/sh
set -e
doas -u git "$@"
/var/ram/git/add-repo.sh
#!/bin/sh
set -e
GREEN='\033[0;32m'
ORG='\033[0;34m'
NC='\033[0m'
type="$1" # Public or private ("public" or "private")
name="$2"
fullname="${name}.git"
# ask if this is what they want
printf "type: %s\nname: %s\nfullname: %s\n" "$type" "$name" "$fullname"
while true; do
read -p "Do you wish to continue? " yn
case "$yn" in
[Yy]* ) break;;
[Nn]* ) exit;;
* ) echo "Please anwer yes or no.";;
esac
done
echo ""
cd "$type"
mkdir "${fullname}"
echo "Created ${fullname}"
cd "${fullname}"
git init --bare > /dev/null
echo "Created git repo"
mv hooks/post-update.sample hooks/post-update
echo "Configured hook"
git gc > /dev/null
git update-server-info > /dev/null
echo -e "Configured git repo\n"
echo -e "${GREEN}Done!${NC}"
echo -e "${ORG}Remember to run ./doas.sh ./update-ref.sh${NC}"
/var/ram/git/update-ref.sh
#!/bin/sh
[ "$1" = "clean" ] && find . -maxdepth 1 -iname "*.git" -exec unlink {} \; && exit 0;
for dir in `find ./public -maxdepth 1 -iname "*.git"`; do
ln -svf "$dir" "$(basename "$dir")"
done
for dir in `find ./private -maxdepth 1 -iname "*.git"`; do
ln -svf "$dir" "$(basename "$dir")"
done
The "real " repo will live inside the private or public folders, we will link them all to the root git folder, because we want to be able to clone them all from the home folder. Create the git user and chown the git folder.
# The password isn't imporatant, it will never be used.
$ adduser -h /var/ram/git git
$ chown -R git:git /var/ram/git
To make doas.sh
work, you need to add this like to /etc/doas.conf
:
permit nopass root
You can test if it works by running:
$ ./doas.sh whoami
It should return git
.
Copy your private keys from /root/.ssh/...
to /var/ram/git/.ssh/
and set the correct permissions.
Create a new user acme with the home /var/db/acme
.
wget acme.sh and install it:
# Inside /var/db/acme running as the acme user.
$ mkdir .acme.sh/
$ mkdir certs/
$ wget https://raw.githubusercontent.com/acmesh-official/acme.sh/master/acme.sh
$ ./acme.sh --install \
--config-home /var/db/acme/.acme.sh/ \
--cert-home /var/db/acme/certs/ \
--accountemail "[email protected]"
# The previus command might say "crontab: can't open 'acme': No such file or directory"
# but that's ok.
# You can now safely remove the acme.sh file.
$ rm -v acme.sh
Because I use nginx, I must allow it to reload to server.
We can give it the permission to reload by adding this line to /etc/doas.conf
:
permit nopass acme cmd /sbin/rc-service args nginx reload
The script writes to /var/ram/www/acme
and therefore you need to chown that directory.
$ chown -R acme:acme /var/ram/www/acme/
To issue a certificate, run the command below:
$ ./.acme.sh/acme.sh --issue -d example.com --webroot /var/ram/www/acme --reloadcmd "doas /sbin/rc-service nginx reload"
v0.5