cgi script can't write to world writable file under apache - ruby

I'm attempting to create a simple CGI script using CentOS 7, Apache 2.4 and Ruby 2.0. All tools installed from official packages.
My script, which resides at /var/www/cgi-bin/test.cgi is:
#!/usr/bin/ruby
puts "Content-Type: text/plain\n\n"
begin
file = File.open("test.log", "a")
file.puts("foobar")
file.close
rescue Exception
puts "pwd: #{`pwd`}"
puts $!.inspect
end
When I load http://myhost/cgi-bin/test.cgi, I get the following:
pwd: /var/www/cgi-bin
#<Errno::EACCES: Permission denied - test.log>
However:
[root#host cgi-bin]# ls -l /var/www/cgi-bin
total 8
-rwxr-xr-x. 1 root root 153 Jul 10 22:03 env.cgi
-rwxr-xr-x. 1 root root 359 Jul 11 00:45 test.cgi
-rw-rw-rw-. 1 root root 0 Jul 11 00:42 test.log
How (and where) can I write data from inside this cgi script if not to a world-writable file in the script's own working directory?

SELinux was blocking the file writes. "setenforce Permissive" allowed them to go through. Edited /etc/sysconfig/selinux and rebooted to make permanent.

Related

Connecting to ProxySQL via socket - "No such file or directory"

I am trying to connect to ProxySQL from PHP with mysqlnd using the local socket, but I get
"No such file or directory"
, as the socket would not exist. The same code can connect to the mysql socket with no problem.
Basically I am reproducing what was described at:
https://www.percona.com/blog/2017/09/19/proxysql-improves-mysql-ssl-connections/
<?php
$i = 10000;
$user = 'percona';
$pass = 'percona';
while($i>=0) {
$mysqli = mysqli_init();
// ProxySQL
$link = mysqli_real_connect($mysqli, "localhost", $user, $pass, "", 6033, "/tmp/proxysql.sock")
or die(mysqli_connect_error());
$info = mysqli_get_host_info($mysqli);
$i--;
mysqli_close($mysqli);
unset($mysqli);
}
?>
This throws:
mysqli_real_connect(): (HY000/2002): No such file or directory
The socket file (/tmp/proxysql.sock) is in fact there:
$ ls -all /tmp
total 12
drwxrwxrwt. 11 root root 4096 Oct 7 17:33 .
dr-xr-xr-x. 28 root root 4096 Sep 20 17:42 ..
drwxrwxrwt. 2 root root 6 Aug 8 02:40 .font-unix
drwxrwxrwt. 2 root root 6 Aug 8 02:40 .ICE-unix
srwxrwxrwx 1 proxysql proxysql 0 Oct 7 17:11 proxysql.sock
I can use the mysql client to connect through it:
$ mysql -u myuser -p --socket /tmp/proxysql.sock --prompt='ProxySQLClient> '
If in the above PHP code I replace the socket file with the MySQL socket, then that works. It is only the proxysql.sock which doesn't work with mysqlnd.
I am using:
mysqlnd version mysqlnd 5.0.12-dev - 20150407
ProxySQL version 2.0.6
Any idea why the proxysql.sock is not accepted by mysqlnd?
UPDATE: Following #EternalHour's suggestion below, I have also tried moving the proxysql.sock file out of /tmp, but unfortunately that didn't make a difference. I am still receiving the same error.
EDIT (2019-10-08): It turns out this issue has nothing to do with PHP, as netcat throws the same problem too, whether the socket files in in /tmp or in /var/sockets/:
$ nc -U /tmp/proxysql.sock
Ncat: No such file or directory.
Out of the 3 nodes of the ProxySQL cluster running on the same OS, same kernel version, 1 has this issue, the other 2 allows connection to the socket file in /tmp/proxsql.sock, although over there too, sometimes restarting ProxySQL results in the socket file being created as private (eg not available to other applications)
Many MySQL Clients have a special handling of the wordlocalhost. localhost doesn't mean "use the resolver to resolve localhost and connect via TCP" but "use unix domain socket on the default path" to use TCP use 127.0.0.1 instead. If proxySQL also provides a unix domain socket provide that path.
I am sorry everyone, the issue was embarrassingly simple - it was simply my fault.
When I was changing the socket file's location in ProxySQL Admin I was using the following
update global_variables set variable_value='0.0.0.0:6033;/tmp/proxysql.sock ' where variable_name='mysql-interfaces';
SAVE MYSQL VARIABLES TO DISK;
Yes, that is a space at the end of "/tmp/proxysql.sock ".
When I was changing it to different locations, I only rewrote the first half of that (the folder), never the filename, so I just keep copying the space and hence always got file or directory not found...
Problem solved!
Sorry about it

Cannot give myself root my permissions

I am trying to give myself root access to all the file in this folder and not have to sudo everything I want to run a command.
The file I am concerned with is pro
When I enter ls -l I get :
drwxr-xr-x+ 12 Guest _guest 384 13 Jan 14:56 Guest
drwxrwxrwt 9 root wheel 288 13 Jan 14:30 Shared
drwxr-xr-x+ 148 Santi staff 4736 1 Apr 17:13 pro
then I enter chmod 775 pro/
It doesnt seem to change the permssions. What can I do to fix this or why is the folder restricting permission even though I appear to be root?
drwxr-xr-x+ ...
the final + means that the file is governed by acl
see
apropos acl : give you the mans to consult
wikipedia
Access Control Lists on Arch wiki

cd command does not see the directory in bash

I have the following bash script:
#!/bin/bash
run_python(){
cd "`dirname $1`"
python "`basename $1`" $2 >test.log
}
crypto_util=/home/dev/src/crypto/util.py
run_python $crypto_util "testpassword"
Somehow cd command fails saying:
cd: /home/dev/src/crypto No such file or directory. I am quite sure the directory exists.
On a side note if I do the following this fails too:
run_python(){
python "$1" $2 >test.log
}
Saying python can not open the file /home/dev/src/crypto/util.py because there is no such file.
Any idea why?
Here is the output of the ll command on the directory/file:
drwxr--r--. 2 dev root 4096 Jun 11 18:56 crypto
-rwxr--r--. 1 dev root 4934 Jun 9 10:50 util.py
Output of ls -llid /home/
654084 drwxr-xr-x. 4 root root 4096 May 8 10:52 /home
Output of ls -lid /home/dev/
924265 drwxr--r--. 4 dev root 4096 Jun 9 09:17 /home/dev/
Output of ls -lid/home/dev/src/:
924266 drwxr--r--. 9 dev root 4096 Jun 9 10:01 /home/dev/src/
Output of ls -lid/home/dev/src/crypto:
924333 drwxr--r--. 2 dev root 4096 Jun 11 18:56 /home/dev/src/crypto/
Output of ls -lid/home/dev/src/crypto/util.py:
924337 -rwxr--r--. 1 dev root 4934 Jun 9 10:50 /home/dev/src/crypto/util.py
some of those dirs don't have x permission bit set - those are needed for entering a directory. Your problem may be that your scripts are running with another user as owner than "dev". dev is the only user allowed to change to those directories.
Set the dirs to +x, and try again.

Can't embed bash command in to Chef Recipe

I'm attempting to embed a shell command in to my Chef Recipe, however when Chef executes the command it seems to get things wrong. Here's the resource in question:
script "create libs symlink" do
interpreter "bash"
user "root"
cwd "/home/robin/test"
code <<-EOH
ln -s $(ls -1 | grep '^[0-9.-]\+$') curr-version-libs
EOH
end
The /home/robin/test directory contains a folder called 19.26-3, so I'm expecting a symlink called curr-version-libs pointing at 19.26-3.
Instead, I'm ending up with a circular symlink:
drwxr-xr-x 4 root root 4096 Jan 17 22:35 19.26-3
drwxr-xr-x 2 root root 4096 Jan 17 22:35 config
lrwxrwxrwx 1 root root 17 Jan 28 17:31 curr-version-libs -> curr-version-libs
It seems that the $(ls -1 | grep '^[0-9.-]+$') is being removed and I'm ending up with the command ln -s curr-version-libs.
Does anyone know what's going on here? I've tried using an execute resource, but I get the same results.
If your 19.26-3 directory exists before chef run starts, then it is easy. If you are creating a symbolic link, I would recommend using link resource for that.
version = `ls /home/robin/test/ -1 | grep '^[0-9.-]+$'`.strip
link "/home/robin/test/curr-version-libs" do
to ::File.join( "/home/robin/test", version )
end
But if it is not there, I would recommend using ruby_block and defining your link resource dynamically.
ruby_block "create libs symlink" do
block do
version = `ls /home/robin/test/ -1 | grep '^[0-9.-]+$'`.strip
res = Chef::Resource::Link.new( "/home/robin/test/curr-version-libs", run_context )
res.to ::File.join( "/home/robin/test", version )
res.run_action :create
end
end
Edit: I corrected the answer by fixing regex and and calling strip before assigning to version as Robin proposed.
It appears you are calling out to the shell to create a sym link. In that case, a much better way to do this is to use the Chef link resource. I would never use the script or execute resource to do what you are doing.
Using the link resource, you would do the following:
link "/home/robin/test/curr-version-libs" do
to '/home/robin/test/19.26-3'
user 'root'
group 'root'
link_type :symbolic
action :create
end
A quick side commentary: I have mentored and tutored a number of folks to come up on Chef. Those who come to understand what is offered by the resources, providers, and lightweight resources (aka. LWRPs) are much happier and effective than those who just try to drop their old shell scripts into their cookbooks.
I highly recommend reading the Resource and Providers and Lightweight Resources Documentation
have you tried escaping dollar sign?
ln -s \$(ls -1 | grep '^[0-9.-]\+$') curr-version-libs

How do i monitor independed applications with god?

I'm currently looking into options for process monitoring of Rails/Ruby Projects and quite like god.
But i cant really find anything on how to monitor multiple applications (for example 2 rails projects running on one machine) with god.
As far as i see it i just set up god (system ruby) and have each project add its own configuration (maybe somehow in a deploy-hook).
This should also work with the projects running different ruby versions (rbenv, rvm) or bundler, since the god ruby does not have to access any project code.
Does anyone already use it like this? Or is there a better approach?
I use god to watch all my stuff (unicorn, redis, resque workers). Basic setup is like this:
God is installed globally, loads on system startup and reads its config file, /etc/god/all.god.
/etc/god/all.god
files = Dir.glob "/etc/god/**/*.god"
files.each do |f|
next if f == '/etc/god/all.god'
God.load f
end
This file loads all config files in /etc/god and its children. Deploy scripts put config files there and tell god to (re)load them.
$ ls -l /etc/god
total 16
-rw-r--r-- 1 root root 108 2012-02-23 16:26 all.god
drwxr-xr-x 2 sergio sergio 4096 2012-03-20 20:59 app1_production
drwxr-xr-x 2 sergio sergio 4096 2012-03-27 00:58 app2_production
drwxr-xr-x 2 root root 4096 2012-04-23 01:37 util
$ ls -l /etc/god/app1_production/
total 0
lrwxrwxrwx 1 sergio sergio 55 2012-03-20 20:59 redis.god -> /srv/app1_production/current/config/god/redis.god
lrwxrwxrwx 1 sergio sergio 56 2012-03-20 20:59 resque.god -> /srv/app1_production/current/config/god/resque.god
lrwxrwxrwx 1 sergio sergio 57 2012-03-20 20:59 unicorn.god -> /srv/app1_production/current/config/god/unicorn.god
Here's a head of unicorn.god.
rails_env = "production"
pid_dir = "/srv/app1_#{rails_env}/shared/pids"
rails_root = "/srv/app1_#{rails_env}/current"
God.watch do |w|
w.name = "unicorn-#{rails_env}"
w.interval = 30.seconds # default
# unicorn needs to be run from the rails root
w.start = "cd #{rails_root} && /home/sergio/.rvm/bin/r193_bundle exec unicorn_rails -c #{rails_root}/config/unicorn/unicorn.#{rails_env}.rb -E #{rails_env} -D"
# QUIT gracefully shuts down workers
w.stop = "kill -QUIT `cat #{pid_dir}/unicorn.pid`"
# USR2 causes the master to re-create itself and spawn a new worker pool
w.restart = "kill -USR2 `cat #{pid_dir}/unicorn.pid`"
As you can see, unicorns are launched via rvm wrappers and therefore each new app can use its own ruby. Also, you provide your own start, stop and restart commands, so you can use god to watch any piece of software.
This approach works very well for me (so far).

Resources