Change peach-web to use systemd system calls #102
4
Cargo.lock
generated
@ -2381,7 +2381,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "peach-config"
|
||||
version = "0.1.17"
|
||||
version = "0.1.21"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"env_logger 0.6.2",
|
||||
@ -2511,7 +2511,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "peach-web"
|
||||
version = "0.6.0"
|
||||
version = "0.6.13"
|
||||
dependencies = [
|
||||
"async-std",
|
||||
"base64 0.13.0",
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "peach-config"
|
||||
version = "0.1.17"
|
||||
version = "0.1.21"
|
||||
authors = ["Andrew Reid <gnomad@cryptolab.net>", "Max Fowler <max@mfowler.info>"]
|
||||
edition = "2018"
|
||||
description = "Command line tool for installing, updating and configuring PeachCloud"
|
||||
|
||||
@ -10,7 +10,7 @@ pub const SERVICES: [&str; 8] = [
|
||||
"peach-buttons",
|
||||
"peach-oled",
|
||||
"peach-dyndns-updater",
|
||||
"peach-go-sbot",
|
||||
"go-sbot",
|
||||
"peach-config",
|
||||
];
|
||||
|
||||
|
||||
@ -5,6 +5,7 @@ use crate::utils::cmd;
|
||||
/// so they can be read and written by all PeachCloud services.
|
||||
pub const CONFIGS_DIR: &str = "/var/lib/peachcloud";
|
||||
pub const PEACH_WEB_DIR: &str = "/usr/share/peach-web";
|
||||
pub const PEACH_HOME_DIR: &str = "/home/peach";
|
||||
|
||||
/// Utility function to set correct file permissions on the PeachCloud device.
|
||||
/// Accidentally changing file permissions is a fairly common thing to happen,
|
||||
@ -15,7 +16,8 @@ pub fn set_permissions() -> Result<(), PeachConfigError> {
|
||||
cmd(&["chown", "-R", "peach", CONFIGS_DIR])?;
|
||||
cmd(&["chgrp", "-R", "peach", CONFIGS_DIR])?;
|
||||
cmd(&["chmod", "-R", "u+rwX,g+rwX", PEACH_WEB_DIR])?;
|
||||
cmd(&["chown", "-R", "peach-web:peach", PEACH_WEB_DIR])?;
|
||||
cmd(&["chown", "-R", "peach:peach", PEACH_WEB_DIR])?;
|
||||
cmd(&["chown", "-R", "peach:peach", PEACH_HOME_DIR])?;
|
||||
println!("[ PERMISSIONS SUCCESSFULLY UPDATED ]");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -4,6 +4,7 @@ use std::fs;
|
||||
|
||||
use crate::error::{FileWriteError, PeachConfigError};
|
||||
use crate::generate_manifest::save_hardware_config;
|
||||
use crate::set_permissions::set_permissions;
|
||||
use crate::setup_networking::configure_networking;
|
||||
use crate::setup_peach_deb::setup_peach_deb;
|
||||
use crate::update::update_microservices;
|
||||
@ -239,6 +240,9 @@ pub fn setup_peach(
|
||||
info!("[ SAVING LOG OF HARDWARE CONFIGURATIONS ]");
|
||||
save_hardware_config(i2c, rtc)?;
|
||||
|
||||
info!("[ SETTING FILE PERMISSIONS ]");
|
||||
set_permissions()?;
|
||||
|
||||
info!("[ PEACHCLOUD SETUP COMPLETE ]");
|
||||
info!("[ ------------------------- ]");
|
||||
info!("[ please reboot your device ]");
|
||||
|
||||
@ -62,8 +62,9 @@ impl SbotStatus {
|
||||
pub fn read() -> Result<Self, PeachError> {
|
||||
let mut status = SbotStatus::default();
|
||||
|
||||
// note this command does not need to be run as sudo
|
||||
// because non-privileged users are able to run systemctl show
|
||||
let info_output = Command::new("systemctl")
|
||||
.arg("--user")
|
||||
.arg("show")
|
||||
.arg("go-sbot.service")
|
||||
.arg("--no-page")
|
||||
@ -83,8 +84,9 @@ impl SbotStatus {
|
||||
}
|
||||
}
|
||||
|
||||
// note this command does not need to be run as sudo
|
||||
// because non-privileged users are able to run systemctl status
|
||||
let status_output = Command::new("systemctl")
|
||||
.arg("--user")
|
||||
.arg("status")
|
||||
.arg("go-sbot.service")
|
||||
.output()?;
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "peach-web"
|
||||
version = "0.6.0"
|
||||
version = "0.6.13"
|
||||
authors = ["Andrew Reid <gnomad@cryptolab.net>"]
|
||||
edition = "2018"
|
||||
description = "peach-web is a web application which provides a web interface for monitoring and interacting with the PeachCloud device. This allows administration of the single-board computer (ie. Raspberry Pi) running PeachCloud, as well as the ssb-server and related plugins."
|
||||
|
||||
@ -1,14 +1,10 @@
|
||||
[Unit]
|
||||
Description=Rocket web application for serving the PeachCloud web interface.
|
||||
Description=Rouille web application for serving the PeachCloud web interface.
|
||||
|
|
||||
|
||||
[Service]
|
||||
User=peach-web
|
||||
Group=www-data
|
||||
User=peach
|
||||
Group=peach
|
||||
WorkingDirectory=/usr/share/peach-web
|
||||
Environment="ROCKET_ENV=prod"
|
||||
Environment="ROCKET_ADDRESS=127.0.0.1"
|
||||
Environment="ROCKET_PORT=3000"
|
||||
Environment="ROCKET_LOG=critical"
|
||||
Environment="RUST_LOG=info"
|
||||
ExecStart=/usr/bin/peach-web
|
||||
Restart=always
|
||||
|
||||
@ -2,8 +2,7 @@
|
||||
set -e
|
||||
|
||||
# create user which peach-web runs as
|
||||
adduser --quiet --system peach-web
|
||||
usermod -g peach peach-web
|
||||
id -u peach &>/dev/null || adduser --quiet peach
|
||||
|
||||
# create nginx config
|
||||
cat <<EOF > /etc/nginx/sites-enabled/default
|
||||
@ -15,16 +14,25 @@ server {
|
||||
rewrite ^/(.*)/$ /$1 permanent;
|
||||
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:3000;
|
||||
proxy_pass http://127.0.0.1:8000;
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
cat <<EOF > /etc/sudoers.d/peach-web
|
||||
# allow peach-web to run commands as peach-go-sbot without a password
|
||||
peach-web ALL=(peach-go-sbot) NOPASSWD:ALL
|
||||
# update sudoers to allow peach-web to stop and restart go-sbot.service
|
||||
mkdir -p /etc/sudoers.d/
|
||||
|
||||
SYSTEMCTL=/bin/systemctl
|
||||
|
glyph
commented
This looks neat. I think it's possible to add a single That being said, I don't mind this explicit approach at all and I like the use of This looks neat. I think it's possible to add a single `NOPASSWD` rule for `systemctl` which then covers all subcommands.
That being said, I don't mind this explicit approach at all and I like the use of `which` to find `systemctl`.
notplants
commented
I was just researching this a bit more. I think people hardcode paths in sudoers allow-rules for security -- if someone could change the PATH and make $(which systemctl) return a path to something else (their own binary) that could maybe be a vulnerability? From this SO post, it sounds like /bin/systemctl should exist on all distros, and might be preferable For covering all subcommands, I guess this is also a security issue. If we all /bin/systemctl it does seem to allow all subcommands, but also for all services, including system services, not just go-sbot. There might be some solution involving wildcards, e.g. systemctl * go-sbot.service , but from my reading about this I also found a bunch of threads about attacks based on this, where people put extra commands to do other things into the wildcard. So maybe hardcoding the path to systemctl, and the specific subcommands we are using, is the safest approach. I was just researching this a bit more.
I think people hardcode paths in sudoers allow-rules for security -- if someone could change the PATH and make $(which systemctl) return a path to something else (their own binary) that could maybe be a vulnerability?
From this SO post, it sounds like /bin/systemctl should exist on all distros, and might be preferable
https://serverfault.com/posts/978288/revisions
For covering all subcommands, I guess this is also a security issue. If we all /bin/systemctl it does seem to allow all subcommands, but also for all services, including system services, not just go-sbot.
There might be some solution involving wildcards, e.g. systemctl * go-sbot.service , but from my reading about this I also found a bunch of threads about attacks based on this, where people put extra commands to do other things into the wildcard.
So maybe hardcoding the path to systemctl, and the specific subcommands we are using, is the safest approach.
glyph
commented
Ah yeah, that's a really good point! Better to enumerate each subcommand individually then.
Hmm...I don't think this is a big issue, in the sense that if an attacker is able to change the path for
That could be the way to go then. I didn't realise there was a single path across distros. Nice :) > For covering all subcommands, I guess this is also a security issue. If we all /bin/systemctl it does seem to allow all subcommands, but also for all services, including system services, not just go-sbot.
Ah yeah, that's a really good point! Better to enumerate each subcommand individually then.
> if someone could change the PATH and make $(which systemctl) return a path to something else (their own binary) that could maybe be a vulnerability?
Hmm...I don't think this is a big issue, in the sense that if an attacker is able to change the path for `systemctl` then the box is probably already compromised in a bad way. Thinking more about the context this `postinst` script runs in: this is run with `sudo`, yeah? Like `sudo apt-get update` or `sudo apt-get install peach-web`?
> From this SO post, it sounds like /bin/systemctl should exist on all distros, and might be preferable
That could be the way to go then. I didn't realise there was a single path across distros. Nice :)
|
||||
START="${SYSTEMCTL} start go-sbot.service"
|
||||
RESTART="${SYSTEMCTL} restart go-sbot.service"
|
||||
STOP="${SYSTEMCTL} stop go-sbot.service"
|
||||
ENABLE="${SYSTEMCTL} enable go-sbot.service"
|
||||
DISABLE="${SYSTEMCTL} disable go-sbot.service"
|
||||
|
||||
cat <<EOF > /etc/sudoers.d/peach-web
|
||||
peach ALL=(ALL) NOPASSWD: $START, $STOP, $RESTART, $ENABLE, $DISABLE
|
||||
EOF
|
||||
chmod 0440 /etc/sudoers.d/peach-web
|
||||
|
||||
# cargo deb automatically replaces this token below, see https://github.com/mmstick/cargo-deb/blob/master/systemd.md
|
||||
#DEBHELPER#
|
||||
@ -29,7 +29,7 @@ pub fn build_template() -> PreEscaped<String> {
|
||||
}
|
||||
}
|
||||
" to start the sbot. If the server starts successfully, you will see a green smiley face on the home page. If the face is orange and sleeping, that means the sbot is still inactive (ie. the process is not running). If the face is red and dead, that means the sbot failed to start - indicated an error. For now, the best way to gain insight into the problem is to check the systemd log. Open a terminal and enter: "
|
||||
code { "systemctl --user status go-sbot.service" }
|
||||
code { "systemctl status go-sbot.service" }
|
||||
". The log output may give some clues about the source of the error."
|
||||
}
|
||||
}
|
||||
|
||||
@ -53,7 +53,6 @@ fn run_on_startup_element(boot_state: &Option<String>) -> Markup {
|
||||
fn database_element(state: &str) -> Markup {
|
||||
// retrieve the sequence number of the latest message in the sbot database
|
||||
let sequence_num = sbot::latest_sequence_number();
|
||||
|
||||
match (state, sequence_num) {
|
||||
// if the state is "active" and latest_sequence_number() was successful
|
||||
("active", Ok(number)) => {
|
||||
@ -62,7 +61,9 @@ fn database_element(state: &str) -> Markup {
|
||||
label class="label-small font-gray" { "MESSAGES IN LOCAL DATABASE" }
|
||||
}
|
||||
}
|
||||
(_, _) => html! { label class="label-small font-gray" { "DATABASE UNAVAILABLE" } },
|
||||
(_, _) => {
|
||||
html! { label class="label-small font-gray" { "DATABASE UNAVAILABLE" } }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -24,8 +24,8 @@ use crate::{error::PeachWebError, utils::sbot};
|
||||
|
||||
/// Executes a systemctl command for the go-sbot.service process.
|
||||
pub fn systemctl_sbot_cmd(cmd: &str) -> io::Result<Output> {
|
||||
Command::new("systemctl")
|
||||
.arg("--user")
|
||||
Command::new("sudo")
|
||||
.arg("systemctl")
|
||||
.arg(cmd)
|
||||
.arg("go-sbot.service")
|
||||
.output()
|
||||
|
||||
I totally fail at pronouncing this but it should be Rouille and not Rule.
roo-lay?