118 lines
3.9 KiB
Text
118 lines
3.9 KiB
Text
|
|
> Is it possible to limit chronyc to only those commands that
|
|
> are readonly plus those necessary to bring a dialup connection up
|
|
> and down? That is: online offline dump writertc and password.
|
|
|
|
This is trivial on the same host and workable for non-local
|
|
hosts: use a wrapper program or script. An *untested*
|
|
sample follows. To use it, best create a special user (say
|
|
chronyc) and a special group (say chronyg). Make the script
|
|
chronyc:chronyg, and 4750 (suid, rwxr-x---). Add all users
|
|
who may run the script to the group chronyg.
|
|
|
|
Make a chrony password file e.g.
|
|
/usr/local/etc/chrony_password. It should be owned by chronyc
|
|
and readable only for the owner, containing only the chrony
|
|
password (and maybe a newline) in the first line.
|
|
|
|
In this way only the script (call it run_chrony, for example)
|
|
can read the password. It will allow only those commands you
|
|
explicitely allow. You can add a password check -- especially
|
|
if you add an internet port so you can access it over the
|
|
internet this is advisable. You really want to add logging
|
|
to this untested script as well.
|
|
|
|
|
|
BTW, if you use some sort of PPP, you probably can use
|
|
/etc/ppp/ip-up and /etc/ppp/ip-down to transparently set chrony
|
|
on- and offline as the ip connection goes up and comes down.
|
|
This is _far_ more user friendly, IMHO, and a DOS by switching
|
|
chrony offline all the time is avoided as well.
|
|
|
|
|
|
#! /usr/bin/perl -T
|
|
use v5.6.1;
|
|
use warnings;
|
|
use strict;
|
|
|
|
sub laundered_command();
|
|
sub order_chrony($$);
|
|
sub read_password();
|
|
sub usage($);
|
|
|
|
our $CHRONY = "/usr/local/bin/chronyc";
|
|
|
|
# NOTE: select the file system protection wisely for the
|
|
# PASSWORDFILE!
|
|
our $PASSWORDFILE = "/usr/local/etc/chrony_password";
|
|
|
|
our @ALLOWED_COMMANDS = (
|
|
'online', # switch online mode on
|
|
'offline', # switch online mode off
|
|
'dump', # save measurements to file
|
|
'writerc', # save RTC accumulated data
|
|
|
|
'clients', # which clients are served by us?
|
|
'rtcdata', # Quality of RTC measurements
|
|
'sources(?: -v)?', # Show our sources (verbose)
|
|
'sourcestats(?: -v)?', # How good are our sources (verbose)?
|
|
'tracking', # whom do we adjust to?
|
|
|
|
# 'burst \d+/\d+', # allow them to send bursts?
|
|
);
|
|
|
|
usage("No command given.") unless $ARGV[0];
|
|
|
|
%ENV = (); # nuke all environment variables. Rather
|
|
# drastic, but better safe than sorry!
|
|
# Add whatever you really need to get it
|
|
# working (again).
|
|
$ENV{'PATH'} = '/usr/local/bin:/bin:/usr/bin';
|
|
|
|
order_chrony(laundered_command(), read_password());
|
|
|
|
exit 0; # command succeeded
|
|
|
|
############################################################
|
|
|
|
sub usage($) {
|
|
print STDERR "Error: ", shift, "\n";
|
|
|
|
# OK, this eats the -v...
|
|
print STDERR "Legal commands are:\n\t", join "\n",
|
|
map { $_ =~ m:(\w+):; $1 } @ALLOWED_COMMANDS;
|
|
exit 1; # error
|
|
}
|
|
|
|
############################################################
|
|
|
|
sub laundered_command() {
|
|
my $regexp = "^(" . join ( "|", @ALLOWED_COMMANDS ) . ")\$";
|
|
my $parameters = join " ", @ARGV;
|
|
$parameters =~ m:$regexp: or usage("Command $parameters not allowed.");
|
|
|
|
return $1; # this value, then, is untainted.
|
|
};
|
|
|
|
############################################################
|
|
|
|
sub read_password() {
|
|
open PASS, $PASSWORDFILE
|
|
or die "Could not read protected password file: $!";
|
|
my $password = <PASS>;
|
|
chomp $password;
|
|
return $password;
|
|
};
|
|
|
|
############################################################
|
|
|
|
sub order_chrony($$) {
|
|
my ($clean_command, $password) = @_;
|
|
open CHRONY, "| $CHRONY &> /dev/null" or die "could not run $CHRONY: $!\n";
|
|
print CHRONY "password $password\n";
|
|
print CHRONY "$clean_command\n";
|
|
close CHRONY
|
|
or die "Error running command $clean_command\n", "\ton $CHRONY: $!\n";
|
|
}
|
|
|
|
############################################################
|