I'm running the code below as part of a Celery task.
class HealthCheckIKEV2:
async def report(self):
try:
client = RedisClient()
proc1 = subprocess.Popen(
["sudo", "/usr/sbin/swanctl", "--list-sas"], stdout=subprocess.PIPE
)
proc2 = subprocess.Popen(
["grep", "INSTALLED"],
stdin=proc1.stdout,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
)
proc3 = subprocess.Popen(
["wc", "-l"],
stdin=proc2.stdout,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
universal_newlines=True,
)
proc1.stdout.close() # Allow proc1 to receive a SIGPIPE if proc2 exits.
proc2.stdout.close() # Allow proc2 to receive a SIGPIPE if proc3 exits.
out, err = proc3.communicate()
info = {
"users": out.rstrip(),
"timestamp": datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S"),
}
client.conn.hset(settings.REDIS_VPN_SUBDOMAIN, mapping=info)
However Celery fails with the following error message:
Jun 13 08:46:42 de-vpn-1 sudo[2038]: celery : user NOT in sudoers ; TTY=unknown ; PWD=/home/admin/app ; USER=root ; COMMAND=/usr/sbin/swanctl --list-sas
Jun 13 08:47:42 de-vpn-1 sudo[2045]: pam_unix(sudo:auth): conversation failed
This is because of this line where the subprocess has to run as sudo to be able to execute /usr/sbin/swanctl.
proc1 = subprocess.Popen(
["sudo", "/usr/sbin/swanctl", "--list-sas"], stdout=subprocess.PIPE
)
What are my options here? Celery documentation says to not give the celery user root access. What can I do to adhere to best practices and yet get this task executed successfully?
One idea I had was to create a new group and add both root and celery users to that group. And change the permission of that file to that group. Sounds a bit hacky though. Thanks.