1

My goal is to make a way to automatically generate SSL certs for people who want to add their site to my CDN service (https://hostcloak.com)

Here is the script that works via SSH, but not when I try to execute it via php

exec("sudo sh /var/autossl $domain 2>&1", $output);

Here is the bash script:

#!/bin/bash

domain=$1

# Set up config file.
cat > /etc/nginx/sites/$domain.conf <<EOF
server {
    listen 80;
    server_name *.$domain;
    root         /var/www/$domain;
}
EOF

nginx -s reload

#########################################

set -o nounset
set -o errexit

mkdir -p /var/www/$domain

# Set up config file.
mkdir -p /etc/letsencrypt
cat > /etc/letsencrypt/cli.ini <<EOF
# Uncomment to use the staging/testing server - avoids rate limiting.
# server = https://acme-staging.api.letsencrypt.org/directory

# Use a 4096 bit RSA key instead of 2048.
rsa-key-size = 4096

# Set email and domains.
email = admin@hostcloak.com
domains = $domain

# Text interface.
text = True
# No prompts.
non-interactive = True
# Suppress the Terms of Service agreement interaction.
agree-tos = True

# Use the webroot authenticator.
authenticator = webroot
webroot-path = /var/www/$domain
EOF

# Obtain cert.
certbot-auto certonly

# Set up daily cron job.
CRON_SCRIPT="/etc/cron.daily/certbot-renew"

cat > "${CRON_SCRIPT}" <<EOF
#!/bin/bash
#
# Renew the Let's Encrypt certificate if it is time. It won't do anything if
# not.
#
# This reads the standard /etc/letsencrypt/cli.ini.
#

# May or may not have HOME set, and this drops stuff into ~/.local.
export HOME="/root"
# PATH is never what you want it it to be in cron.
export PATH="\${PATH}:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"

certbot-auto --no-self-upgrade certonly

# If the cert updated, we need to update the services using it. E.g.:
if service --status-all | grep -Fq 'apache2'; then
  service apache2 reload
fi
if service --status-all | grep -Fq 'httpd'; then
  service httpd reload
fi
if service --status-all | grep -Fq 'nginx'; then
  service nginx reload
fi
EOF
chmod a+x "${CRON_SCRIPT}"

#####################################

# Set up config file.
cat > /etc/nginx/sites/$domain.conf <<EOF
        server {

        listen 80;
                server_name *.$domain;
                location / {
                        proxy_set_header x-real-IP \$remote_addr;
                        proxy_set_header x-forwarded-for \$proxy_add_x_forwarded_for;
                        proxy_set_header host \$host;
                        proxy_pass http://google.com;
                        }
                }

        server {
        listen 443;
                server_name *.$domain;
                ssl_certificate /etc/letsencrypt/live/$domain/fullchain.pem;
                ssl_certificate_key /etc/letsencrypt/live/$domain/privkey.pem;
                ssl on;
                ssl_session_cache builtin:1000 shared:SSL:10m;
                ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
                ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
                ssl_prefer_server_ciphers on;
                location / {
                        proxy_set_header x-real_IP \$remote_addr;
                        proxy_set_header x-forwarded-for \$proxy_add_x_forwarded_for;
                        proxy_set_header host \$host;
                        proxy_pass http://google.com;
                }
        }
EOF

nginx -s reload

"autossl" works when directly used via ssh console, however when I try it via php's exec function, it says "command not found" for "nginx -s reload"

So my question is: How do I achieve this via PHP (it has to be automated by my website)

John
  • 27
  • 1
  • 4

2 Answers2

1

Think about what you are trying to do here. You are asking www-data (or whatever user account your webserver is running as) to issue a sudo command. It probably doesn't even have su privileges. Even if it did, what happens when you first try to use sudo? You have to enter your password...

You can disable password requirements on an individual basis, but I wouldn't recommend giving www-data sudo rights. Have your website add requests to a database or something and poll that every few minutes as a cron job from a user with su priveleges and have that account do the su stuff

miknik
  • 5,748
  • 1
  • 10
  • 26
  • Yes this is a better solution, a simple file queue will do. – Scriptonomy Oct 18 '17 at 03:41
  • Yes, I've added nopassword for ngixin in visudo, however, it still asks for password. I've issued 'whoami' with php exec and it gives nginx, still asks for password tho. :( – John Oct 18 '17 at 04:35
0

Quick answer: replace sh with bash in exec function or modify your script to work with sh

Explanation: you can find here, in this stackoverflow thread

M. Galczynski
  • 634
  • 1
  • 5
  • 12
  • Tried that, but I get this: Array ( [0] => /usr/local/bin/autossl: line 6: /etc/nginx/sites/yoyyo.com.conf: Permission denied [1] => /usr/local/bin/autossl: line 14: nginx: command not found [2] => Requesting to rerun /usr/local/bin/certbot-auto with root privileges... [3] => [4] => We trust you have received the usual lecture from the local System [5] => Administrator. It usually boils down to these three things: [6] => [7] => #1) Respect the privacy of others. [8] => #2) Think before you type. [9] => #3) With great power comes great responsibility. [10] => [11] => sudo: no tty present an... – John Oct 18 '17 at 00:31
  • Hmmm, first error is probably because php/nginx have other privileges that your user, second caused because nginx command is not in path of php/nginx bash – M. Galczynski Oct 18 '17 at 00:38
  • How do I add it to the path of php/nginx bash ? – John Oct 18 '17 at 00:38
  • I don't know exactly how to add for user without home directory but you can use provide full path of nginx command in script like `/usr/bin/nginx`, or you can set path system wide eg. in ubuntu [ubuntu-docs](https://help.ubuntu.com/community/EnvironmentVariables) - Paragraph System-wide environment variables or you can set path in script using export PATH command – M. Galczynski Oct 18 '17 at 00:50