Solved Environmental variable in a jail

I'd like to set an environmental variable that could be set when the jail starts.

In the command line (csh), if i do:

Code:
>setenv KK "whatevercsh"
>printenv  | grep KK
KK=whatevercsh

In the command line (bash), it also works although with:
Code:
# KK="whateverbash"; export KK                                                                                                                                                                                                        
# printenv | grep KK
KK=whateverbash

Fine.
But what about having it when the jail is started?
Tried to place KK="whateversh"; export KK in /etc/rc.local as it seems that /etc/rc.local is interpreted by /bin/sh, but KK was never set.
Also tried to call a script from /etc/rc.local, either in the csh or the bash versions of it, but the variable remained not set.

From the man page of rc.local(8), it's said:
if you want to use rc.local, it is still supported. In this case, it should source /etc/rc.conf and contain additional custom startup code for your system.

Tried to do this. cat /etc/rc.local:
Code:
. /etc/rc.conf
KK="whatever"; export KK

But to no success.

So, my question. How to set a variable at the boot of a jail?
 
I'd like to set GOPATH for a Go system.
I test it like printenv | grep KK.
Or when under a bash prompt, set | grep KK.
 
I test it like printenv | grep KK.
Or when under a bash prompt, set | grep KK.
Where and how are you executing this in the jail? The way you access the shell can be done through different ways. Shells typically use different files when started interactive vs. non-interactive and login vs. non-login. For sh(1) for example, the /etc/profile is only loaded when it's a login shell. Bash is even worse when it comes to startup scripts.
 
Where and how are you executing this in the jail? The way you access the shell can be done through different ways. Shells typically use different files when started interactive vs. non-interactive and login vs. non-login. For sh(1) for example, the /etc/profile is only loaded when it's a login shell. Bash is even worse when it comes to startup scripts.
Yes, I know. That's why I didn't do it before. But since Wozzeck.Live mentioned it, I also tested it.
 
An environment is set for a specific proces. A jail is simply a collection of processes chrooted in a specific base directory.
So you have to tell us in which process you need the environment variable set?

For example if you open a console in the jail (csh, bash or whatever shell) and you want to have it in your shell environment, then you simply use /.bashrc or /.profile just like outside the jail. Put the environment variable in $jailRoot/home/YourUser/.bashrc or .cshrc.

If you run a specific script or service in the jail (a Go program, for example), then you need to put the environment variable in the environment of that process. This depends on how do you start the process.
For example, if you run a Go program by calling a starter script in the jail with exec.poststart, then you could put the environment variable in the starter script.
It depends on your concrete solution for starting the jail and in which process do you need the variable.
 
If you run a specific script or service in the jail (a Go program, for example), then you need to put the environment variable in the environment of that process. This depends on how do you start the process.
For example, if you run a Go program by calling a starter script in the jail with exec.poststart, then you could put the environment variable in the starter script.
It depends on your concrete solution for starting the jail and in which process do you need the variable.
It's for this scenario.

Did a grep for poststart in all /usr/local/etc/qjail* and only found options for poststartssh.
Included a poststart option to /usr/local/etc/qjail.global/nameofjail, like /usr/local/bin/bash /home/myuser/go/goprog, but the program didn't start. If it started, I'd try to set the variable before that invocation.

Where should I place that poststart option when using qjail?
 
Well, this is easy. Instead of calling /usr/local/bin/bash with goprog, create a wrapper script and call the script in poststart:

exec.poststart = "/usr/local/bin/bash /home/myuser/wrapperscript.sh"
Bash:
#!/usr/local/bin/bash

export myvar=....

$SHELL /home/myuser/go/goprog
 
By the way, also: You can try to set the variable directly in the jail.conf. This should also be possible but I have not tested it:

Bash:
exec.poststart += "set myvar ..."
exec.poststart += "/usr/local/bin/bash /home/myuser/go/goprog"
 
Well, this is easy. Instead of calling /usr/local/bin/bash with goprog, create a wrapper script and call the script in poststart:

exec.poststart = "/usr/local/bin/bash /home/myuser/wrapperscript.sh"
Bash:
#!/usr/local/bin/bash

export myvar=....

$SHELL /home/myuser/go/goprog
Calling the goprog under a sub-shell returned an error, either when called as a jail.conf parameter, or when in the jail's command line. I wonder why...
Code:
/usr/home/myuser/go/goprog: 1: Syntax error: Bad escape sequence
/usr/home/myuser/go/goprog: 1: Syntax error: Error in command substitution
But, on the command line, if it's called directly, i.e., ~/go/goprog & it runs fine.


By the way, also: You can try to set the variable directly in the jail.conf. This should also be possible but I have not tested it:

Bash:
exec.poststart += "set myvar ..."
exec.poststart += "/usr/local/bin/bash /home/myuser/go/goprog"
exec.poststart is run on the system environment and that's not what I needed.
When the command is run as exec.start it's run on the jail environment, once again, with no sub-shell.
For the record, just have to edit the file /usr/local/etc/qjail.config/myjail, as I'm using qjail:
Code:
exec.start          =  "/bin/sh /etc/rc";
exec.start         +=  "/usr/home/myuser/go/goprog &";

Thank you very much roccobaroccoSC , SirDice and even to the other user that seemed to have removed the answers.
 
Hi, you have to know what "goprog" is. I assumed it was a bash script.
Use this command to see what type of file it is: file $jailRoot/usr/home/myuser/go/goprog, also see if the executable permissions are set for the file: ls -l $jailRoot/usr/home/myuser/go/goprog. If not, you can set them with chmod a+x $jailRoot/usr/home/myuser/go/goprog.
If it is a binary program or a script with execute permissions, simply start it with its name, don't put /usr/local/bin/bash before it.

Point 2. Yes, true. Use exec.start. Poststart runs outside the jail, it's no good.

So you almost got it. Instead of goprog, run the wrapper script above (but without /usr/local/bin/bash):
Code:
exec.start          =  "/bin/sh /etc/rc";
exec.start         +=  "/usr/local/bin/bash /usr/home/myuser/wrapper_script.sh &";
 
Hi,

I did some modifications because:
  1. although the goprog was working, the environmental variable was not set
  2. I wanted goprog to run under a different user

So in /usr/local/etc/qjail.config/myjail changed exec.start += "/usr/home/myuser/wrapperscript.sh &";
and cat /home/myuser/wrapperscript.sh to:

Code:
  #!/bin/sh
  export ZZZZZZZZ="whatever" && /usr/bin/su - myuser -c '/home/myuser/go/goprog'

Also changed the way I entered the jail, from
qjail console -z myzone -u root -c /usr/local/bin/bash myjail
to
qjail console -z myzone -u root myjail

With all this, I accomplished to enter the jail at SHLVL=1 and to have 2) satisfied.
But the environmental variable ZZZZZZZZ doesn't want be set somehow.

Any ideas?
 
Your script syntax is wrong!
If using /bin/sh, you cannot use export. This is the bash syntax.
Either change the Shebang line to #!/usr/local/bin/bash or use the /bin/sh syntax in the script.

Also - the error messages should be visible in the jail log file. Always read the log to see what's happening.
The log is set in jail.conf via exec.consolelog.

Also - I think you can remove the "&" at the end of exec.start. I don't think it's necessary.
 
Your script syntax is wrong!
If using /bin/sh, you cannot use export. This is the bash syntax.
Either change the Shebang line to #!/usr/local/bin/bash or use the /bin/sh syntax in the script.
I wish it was wrong, but I'm afraid it isn't. You can check the manual of sh(1)

Also - the error messages should be visible in the jail log file. Always read the log to see what's happening.
The log is set in jail.conf via exec.consolelog.
Don't have any errors relating to setting the environmental variable...


The only way it works is to include that information in /etc/profile, like suggested by Wozzeck.Live
I was afraid that it would only work when I entered the jail, as refered by SirDice , but that's not true.
In the usr/local/etc/qjail.config/myjail (that seems to substitute jail.conf) there's a default parameter exec.start = "/bin/sh /etc/rc"; that ensures that /bin/sh is always executed.
So, the environmental variables are visible for every process inside the jail.

Another thing is a variable only seen by some process, but for that I'll have to do some other tests.
 
I wish it was wrong, but I'm afraid it isn't. You can check the manual of sh(1)


Don't have any errors relating to setting the environmental variable...


The only way it works is to include that information in /etc/profile, like suggested by Wozzeck.Live
I was afraid that it would only work when I entered the jail, as refered by SirDice , but that's not true.
In the usr/local/etc/qjail.config/myjail (that seems to substitute jail.conf) there's a default parameter exec.start = "/bin/sh /etc/rc"; that ensures that /bin/sh is always executed.
So, the environmental variables are visible for every process inside the jail.

Another thing is a variable only seen by some process, but for that I'll have to do some other tests.
But see what is going on in the script:
  • first you export the variable
  • then you open a new shell with "su" and the new shell does not have it. sudo deletes the environment.

See for yourself:
Code:
sh
ZZZZZZZZ="whatever"; export ZZZZZZZZ; /usr/bin/su - root -c env | grep ZZZ

# output is empty

I don't think the jail is the problem, you have to get your script right.
Test and debug the script directly in the console without a jail. When you get it right, then install it in the jail.

 
Again, it depends on what you want to do. If you want the variable to be visible to all the processes, /etc/profile (inside the jaill!) might be a good idea. I don't know though if the file is read only for interactive shells or for all the processes, you need to check that.
If you want to set the variable only for a specific process, I would use a wrapper script.
 
See for yourself:
Code:
sh
ZZZZZZZZ="whatever"; export ZZZZZZZZ; /usr/bin/su - root -c env | grep ZZZ

# output is empty
I don't think the jail is the problem, you have to get your script right.
Test and debug the script directly in the console without a jail. When you get it right, then install it in the jail.
Removing the ` - ` from the `su` command makes all the difference, as it clears the environment.
So, in the wrapperscript.sh, called from the equivalent `qjail` of jail.conf,
Code:
 exec.start         +=  "/usr/home/myuser/wrapperscript.sh &";

Code:
#!/bin/sh
ZZZZZZZZ="whateverwrapp"; export ZZZZZZZZ; /usr/bin/su myuser -c env | grep ZZZ > /home/myuser/ZZFile
Shows that the value of `ZZZZZZZZ` is indeed written to the file /home/myuser/ZZFile.

So, in conclusion, set the variable in /etc/profile to be seen jail wide. Set it as the above `su` to be set for that process.

The funny thing is that the variable `ZZZZ`, that is set in /etc/profile, doesn't get written to /home/myuser/ZZFile.
 
If you set the variable in the wrapper script, it would overwrite a variable with the same name from /etc/profile. That's why you see only one value - the variable cannot have two values at the same time.
 
Back
Top