Reading a file as sudo from Ruby on Rails - ruby-on-rails

Surprisingly i did not find anyone trying to do this, that's why im making this question.
Thing is i have a file, where im storing some data. I want to have an option in my rails project, where you can "export" some objects that are defined in this file.
This file belongs to root, soo if i try to read it with File.read("myfile.json") it fails with this error:
#<Errno::EACCES: Permission denied # rb_sysopen - /opt/rb/etc/cep/state.json>
Is there a way i can read it as root? Maybe the solution is to run a "sudo cat myfile.json" as a command from ruby and inject the result into a variable?
My goal is to place the contents of this file inside another one that the user will download, so later he can upload this file and have all the objects from before. It was weird not seeing more people trying to do this so I don't know if maybe i'm asking something stupid. I found none information in google about this, maybe is not possible to open a file as sudo with File.open.

A simple way to quickly solve it is change the file's owner.
sudo chown $USER myfile.json

If you want to access a file, I think it's not a good idea to give your application sudo access. It is potentially dangerous.
You might change the permission on the file instead, by changing the owner/group for the file.
Here you can find how to get the user running the application.
This command will change the owner of the file
sudo chown <my_user> /opt/rb/etc/cep/state.json
Another option is to create a group with the current owner and the rails user and set that group as owner:
sudo groupadd mynewgroup
sudo usermod -a -G mynewgroup <my_user>
sudo usermod -a -G mynewgroup <current_user>
sudo chgrp mynewgroup /opt/rb/etc/cep/state.json

Related

System user in Ubuntu server does not search right TexLive path

Short question: my system user (name sharelatex) does not search in manually installed TexLive in /usr/local/texlive but search in /usr/share/texlive (I don't know why there is this folder here, I didn't install TexLive from Ubuntu repo). My another normal user and root user can search well in /usr/local/texlive. How can I force sharelatex user to search in /usr/local/texlive? Thanks!
Detail: I'm trying to install sharelatex onto my Ubuntu server.
I have manually installed TexLive using:
wget http://mirror.ctan.org/systems/texlive/tlnet/install-tl-unx.tar.gz
tar -xvf install-tl-unx.tar.gz
cd install-tl-*
sudo ./install-tl
While installing, I have created a system user named sharelatex and added it to group sharelatex by these 2 commands:
sudo adduser --system --home /var/www/sharelatex --no-create-home --group sharelatex
sudo chown -R sharelatex:sharelatex /var/www/sharelatex
When I login as root or normal user, the output of the command
which latex
is
/usr/local/texlive/2015/bin/x86_64-linux/latex
However,when I try to run the same command as sharelatex user:
sudo -u sharelatex which latex
the output is
/usr/bin/latex
I also think this was the problem about $PATH with system user sharelatex. Even I have tried to put my TexLive directory to /etc/environment, my sharelatex user still cannot find it. However, after take a closer look at sharelatex service files, I see that the path for sharelatex seems to be set again when sharelatex execute latex command. Here is how to fix it:
Step 1. Search for your upstart files sharelatex-SERVICE.conf where SERVICE should be replaced with web, chat,clsi,... Full list as below:
sharelatex-chat.conf
sharelatex-clsi.conf
sharelatex-docstore.conf
sharelatex-document-updater.conf
sharelatex-filestore.conf
sharelatex-real-time.conf
sharelatex-spelling.conf
sharelatex-tags.conf
sharelatex-template.conf
sharelatex-track-changes.conf
sharelatex-web.conf
If you follow the installation manual from sharelatex github, these files are probably in /etc/init.
Step 2. In each file, you will see this line:
LATEX_PATH=/usr/local/texlive/2015/bin/x86_64-linux
This line will set LATEX_PATH variable to the right TexLive. And in the ending of the file, you will see the line that will execute TexLive command:
exec sudo -u $USER -g $GROUP env SHARELATEX_CONFIG=$SHARELATEX_CONFIG NODE_ENV=production PATH=$PATH:$LATEX_PATH $NODE app.js >> /var/log/sharelatex/$SERVICE.log 2>&1
What you need to do it to swap $PATH:$LATEX_PATH to become PATH=$LATEX_PATH:$PATH. By doing this, the directory to the right TexLive will be search first.
Make this change to all the sharelatex-SERVICE.conf listed above.
After editing all those files, you might want to restart all those services (search for restart upstart services), or maybe just restart the machine.

How to set right permission to Linux file?

I wanted to know how can I set right permission for my file /log/production.log? Everyone is saying just use chmod or chown but no one explains what I should wright after these commands. I am beginner and would appreciate if you could explain.
In my particular example I have rails app on production server where I need to set permission to production.log file in /var/www/my_app/log/ directory.
Here is what documentation is asking from me:
By default, Phusion Passenger runs Rails applications as the owner of
config.ru. So the log file can only be written to if that user has
write permission to the log file. Please chmod or chown your log file
accordingly.
Hope you can help. Thanks.
Try chmod 0660 production.log and take a look at this explanation/diagram of chmod.
chmod allows change the permissions of a file or a directory. Exists three basic permissions (read,write,execute) for three differents groups (owner,group,other).
chown allows change who is the owner of a file or a directory.
I recommend you use chmod 640. Looking the syntax of chmod here you're defining the production.log's owner (usually root) can read and write this file. If you want, you can give read-access for all users of the same group of the owner. But you shouldn't offer permissions for other people, even less in a production environment.
I would create a deploy user for your application, say myapp (doesn't particularly matter what the name is). The use this user to deploy/manage your application. Assuming username myapp
chown -R myapp:myapp /var/www/my_app
and then restart nginx/passenger. This will cause passenger to run as the myapp user, and allow it to write logs under the logs directory. (Also make sure that you don't have /var/www as the docroot, accessible outside of passenger as it can cause information leakage)
another option, if the server isn't shared, is that you can run as the www user. so
chown -R www:www /var/www/my_app
which should allow the process to write to your logs.

nginx.conf (permission to write denied). How do I fix this?

So I am trying to follow the tutorial here: https://gorails.com/deploy/ubuntu/14.04 to deploy a Rails app. When I tried to edit the nginx.conf at (/etc/nginx/nginx.conf) file, it tells me I have read only permission, even though I followed the steps(with setting the permissions) previously. How do I fix this?
you need sudo to edit that file, because it's owned by root user,
use sudo nano /etc/nginx/nginx.conf or sudo vim /etc/nginx/nginx.conf which ever editor you prefer.

Non-privileged, non-root, user to start or restart webserver server such as nginx without root or sudo

I'm using capistrano to deploy a rails web app. I want to give the deploy user on the webserver as few privileges as I can. I was able to do everything I need to do as a non-privileged user except restart the webserver.
I'm doing this on an ubuntu server, but this problem is not specific to my use case (rails, capistrano, deployment), and I've seen a lot of approaches to this problem that seem to involve poor security practices. Wondering whether others can vet my solution and advise whether it's secure?
First, not necessary, but I have no idea why /etc/init.d/nginx would need any (even read) access by other users. If they need to read it, make them become root (by sudo or other means), so I:
chmod 750 /etc/init.d/nginx
Since the ownership is owner root, group root (or can be set such with chown root:root /etc/init.d/nginx) only root, or a user properly sudo'ed, can read, change or run /etc/init.d/nginx, and I'm not going to give my deploy user any such broad rights. Instead, I'm only going to give the deploy user the specific sudo right to run the control script /etc/init.d/nginx. They will not be able to run an editor to edit it, because they will only have the ability to execute that script. That means that if a someone gets access to my box as the deploy user, they can restart and stop, etc, the nginx process, but they cannot do more, like change the script to do lots of other, evil things.
Specifically, I'm doing this:
visudo
visudo is a specific tool used to edit the sudoers file, and you have to have sudoer privileges to access it.
Using visudo, I add:
# Give deploy the right to control nginx
deploy ALL=NOPASSWD: /etc/init.d/nginx
Check the sudo man page, but as I understand this, the first column is the user being given the sudo rights, in this case, “deploy”. The ALL gives deploy access from all types of terminals/logins (for example, over ssh). The end, /etc/init.d/nginx, ONLY gives the deploy user root access to run /etc/init.d/nginx (and in this case, the NOPASSWD means without a password, which I need for an unattended deployment). The deploy user cannot edit the script to make it evil, they would need FULL sudo access to do that. In fact, no one can unless they have root access, in which case there's a bigger problem. (I tested that the user deploy could not edit the script after doing this, and so should you!)
What do you folks think? Does this work? Are there better ways to do this? My question is similar to this and this, but provides more explanation than I found there, sorry if it's too duplicative, if so, I'll delete it, though I'm also asking for different approaches.
The best practice is to use /etc/sudoers.d/myuser
The /etc/sudoers.d/ folder can contain multiple files that allow users to call stuff using sudo without being root.
The file usually contains a user and a list of commands that the user can run without having to specify a password. Such as
sudo service nginx restart
Note that we are running the command using sudo. Without the sudo the sudoers.d/myuser file will never be used.
An example of such a file is
myuser ALL=(ALL) NOPASSWD: /usr/sbin/service nginx start,/usr/sbin/service nginx stop,/usr/sbin/service nginx restart
This will allow the myuser user to call all start, stop and restart for the nginx service.
You could add another line with another service or continue to append them to the comma separated list, for more items to control.
Also make shure you have run the command below to secure things
chmod 0440 /etc/sudoers.d/myuser
This is also the way I start and stop services my own created upstart scripts that live in /etc/init
It can be worth checking that out if you want to be able to run your own services easily.
Instructions:
In all commands, replace myuser with the name of your user that you want to use to start, restart, and stop nginx without sudo.
Open sudoers file for your user:
$ sudo visudo -f /etc/sudoers.d/myuser
Editor will open. There you paste the following line:
$ myusername ALL=(ALL) NOPASSWD: /usr/sbin/service nginx start,/usr/sbin/service nginx stop,/usr/sbin/service nginx restart
Save by hitting ctrl+o. It will ask where you want to save, simply press enter to confirm the default. Then exit out of the editor with ctrl+x.

Running system call in rails causes error

When I try to run the following code:
system("pdftk #{##temp_file_path} output #{##file_path} user_pw #{##pass}")
I get this error:
Permission denied - /tmp/billing.pdf
I tried running:
chmod +x /tmp
But that didn't help.
Any suggestions?
What are the permissions on /tmp (you can find this with 'ls -ld /tmp')? Are you trying to create billing.pdf or modify an existing file?
The user executing your rails process probably needs write privilege in addition to execute privilege (which you were adding with the 'chmod +x' command). Also, if there's already a billing.pdf file in /tmp, it would need to allow the rails user to read or write it (whatever you're trying to do).
Adding this system call first fixed the problem:
system("chmod +w ##temp_file_path")
For some reason rails pdf-writer plugin generates files as read only.
Maybe it has options to override that. :)

Resources