We were able to fix our TMPDIR directory issue by specifying the --server-data-dir as we did previously. However, when implementing that we are no longer able to authenticate with the export RSTUDIO_AUTH="${PWD}/bin/auth and it doesn’t give us any output to suggest where the problem with authentication is.
Here is our current script:
# Purge the module environment to avoid conflicts
#module purge
module load shared
# Load the required modules
module load R/3.6.3_GCC-9.3.0
module load python/3.8.0
#module load rstudio/.1.3.1093
module load pbspro/2020.1
# log statements
echo $PATH
module list
which R
which python
python --version
which python3
python3 --version
echo $LD_LIBRARY_PATH
# Load the required environment
setup_env () {
# Additional environment which could be moved into a module
# Change these to suit
# export RSTUDIO_SERVER_IMAGE="/depot/apps/singularity_images/3.6.0/rserver-launcher-centos7.simg"
# export SINGULARITY_BINDPATH="/gpfs,/cm,/etc,/media,/mnt,/opt,/srv,/usr,/var,/depot,/active,/archive"
export PATH="$PATH:/usr/lib/rstudio-server/bin"
# export SINGULARITYENV_PATH="$PATH"
export MODULEPATH="$MODULEPATH:/depot/Modules/modulefiles"
# In Singularity 3.5.x it became necessary to explicitly pass LD_LIBRARY_PATH
# to the singularity process
# export SINGULARITYENV_LD_LIBRARY_PATH="$LD_LIBRARY_PATH"
}
setup_env
# Start RStudio Server
#
# PAM auth helper used by RStudio
export RSTUDIO_AUTH="${PWD}/bin/auth"
export RSTUDIO_HOME="${PWD}"
# Generate an `rsession` wrapper script
export RSESSION_WRAPPER_FILE="${PWD}/rsession.sh"
(
umask 077
sed 's/^ \{2\}//' > "${RSESSION_WRAPPER_FILE}" << EOL
#!/usr/bin/env bash
# Log all output from this script
export RSESSION_LOG_FILE="${PWD}/rsession.log"
exec &>>"\${RSESSION_LOG_FILE}"
# Launch the original command
echo "Launching rsession..."
set -x
exec rsession --r-libs-user "${R_LIBS_USER}" "\${@}"
EOL
)
chmod 700 "${RSESSION_WRAPPER_FILE}"
# Set working directory to home directory
cd "${HOME}"
export TMPDIR="$(mktemp -d)"
export RS_SESSION_TMP_DIR="$TMPDIR"
echo $RS_SESSION_TMP_DIR
mkdir -p "$TMPDIR/rstudio-server"
python -c 'from uuid import uuid4; print(uuid4())' > "$TMPDIR/rstudio-server/secure-cookie-key"
chmod 0600 "$TMPDIR/rstudio-server/secure-cookie-key"
set -x
# Launch the RStudio Server
echo "Starting up rserver..."
#singularity run -B "$TMPDIR:/tmp" "$RSTUDIO_SERVER_IMAGE" \
rserver \
--www-port "${port}" \
--auth-none 0 \
--auth-pam-helper-path "${RSTUDIO_AUTH}" \
--auth-encrypt-password 0 \
--rsession-path "${RSESSION_WRAPPER_FILE}" \
--server-user "$USER" \
--server-data-dir "${RSTUDIO_HOME}"
# --server-data-dir "${TMPDIR}"
#echo 'Singularity has exited...'
I feel like this is a problem with how the RSTUDIO_AUTH parameter is being passed into the URL for ondemand. Unfortunately I just don’t know how to fix that piece as I am not seeing a definitive error to say it is a problem. No logs or errors are being generated with clicking the “connect to Rstudio” but if I try to enter my username and the generated password I see an error in the rstudio 1.3 UI but no where else. If I try to type in an arbitrary (non-existing user) like “user: rstudio” “password: rstudio” it will error out in the logs saying there was a problem with pam auth for user ‘rstudio’
#!/usr/bin/env bash
# Confirm username is supplied
if [[ $# -ne 1 ]]; then
echo "Usage: auth USERNAME"
exit 1
fi
USERNAME="${1}"
# Confirm password environment variable exists
if [[ -z ${RSTUDIO_PASSWORD} ]]; then
echo "The environment variable RSTUDIO_PASSWORD is not set"
exit 1
fi
# Read in the password from user
read -s -p "Password: " PASSWORD
echo ""
if [[ ${USERNAME} == ${USER} && ${PASSWORD} == ${RSTUDIO_PASSWORD} ]]; then
echo "Successful authentication"
exit 0
else
echo "Invalid authentication"
exit 1
fi
… Okay so can confirm replacing ‘-ne’ with ‘-lt’ in the template/bin/auth totally fixed our issue. I absolutely love that this worked and thanks for the call out… but dang SO much time for that one issue.
Full info + Solution: Thanks to @dugan and @maflister
For those who run into this in the future here is the changes that had to be implemented:
Installed rstudio 1.3.1093 natively with the rpm (will test with source later) yum install -y rstudio-server-rhel-1.3.1093-x86_64.rpm
In thetemplate/script.sh.erb ensure you use the following :
If you haven’t already, you need to update the template/bin/auth and change the ‘-ne’ flag to ‘-lt’
#!/usr/bin/env bash
# Confirm username is supplied
if [[ $# -lt 1 ]]; then
echo "Usage: auth USERNAME"
exit 1
fi
USERNAME="${1}"
# Confirm password environment variable exists
if [[ -z ${RSTUDIO_PASSWORD} ]]; then
echo "The environment variable RSTUDIO_PASSWORD is not set"
exit 1
fi
# Read in the password from user
read -s -p "Password: " PASSWORD
echo ""
if [[ ${USERNAME} == ${USER} && ${PASSWORD} == ${RSTUDIO_PASSWORD} ]]; then
echo "Successful authentication"
exit 0
else
echo "Invalid authentication"
exit 1
fi
What type of logging or error feedback would have helped reduce the amount of time it took to debug this issue? Perhaps there is something we can change in OnDemand to help with debugging problems like this in the future.
Not sure how to accomplish it, but some kind of logging on wether the pam auth found in template/bin/auth was actually being invoked or if it failed out because of syntax would be nice. It was really hard to pinpoint what the actual problem was because as far as we could see there wasn’t anything “erroring”.
If that level of error logging does exist we didn’t have a good place to reference that in the documentation.
I have this same issue with Rstudio server 1.4 container, but not 1.2 or 1.3. Has anyone been able to find the magic to fix it for 1.4 please?
Inspecting the “connect to” part of the web page shows the user/pass being stored correctly, but i have to manually enter them on the next screen in order to enter rstudio
I feel something was changed since in the 1.3.x if I enter the “auth-do-sign-in” url I get:
Redirected to “auth-sign-in?error=1”
An error: “Error: Incorrect or invalid username/password”
and that’s expected since I’m just entering it in the browser (GET request without parameters)
But if I do the same in the version 1.4.x I get:
Redirected to “auth-sign-in?appUri=appUri&error=2”
An error: “Error: Temporary server error, please try again”
So either this authentication method got deprecated (maybe it there’s a different url to send the request) or that’s not working “by default” and needs some configuration in “rserver.conf” file.
I’m trying to understand more but if there’s anyone with more expertise which may help it could be useful. @maflister are you saying this is a known bug which RStudio folks are working on?
I think it is related (since I feel that’s something they are removing) but the helper itself still works since if you use your userID and the password generated in the “before” script (stored in the connection.yml file) it lets you in.
This is also still documented by “rocker” team in the “singularity” section for their rstudio:4.0.4 (which has rstudio server 1.4.x): Rocker Project
So I’m pretty sure pam authentication still works.
7.3.1.2 Custom login templates now must include a CSRF token field
Shiny Server Pro 1.4.6 includes mitigations against CSRF attacks. For the most part, this should not affect your installation of Shiny Server Pro. The exception is if you are using a custom template for your login page. In that case, you’ll need to add a new field to your login <form> tag:
I really used “TOKEN” as token and it worked but it needs to have it as cookie (I couldn’t find if it is stored on the server side).
I’ll stop here and see if anyone can help from this point.
So I declare a variable in ruby to be used as TOKEN and, in the “script” I set it as cookie for the rstudio page.
This can then be specified as “csrf-token” in the POST request. The rest of the file stays the same.
This is an “hello world” of the solution. The TOKEN can clearly be a better one.
Let me know if this works for you as well.
Very cool, @fenz! I mistakenly thought that we had to use the random cookie generated by the server but you show that the server will accept whatever the client sets. It does make me wonder what additional security this csrf-token is providing. Thanks.
should be without “/” at the end of the path, like: document.cookie = "csrf-token=<%= csrftoken %>; path=/rnode/<%= host %>/<%= port %>; secure";
Since with the “/” RStudio seems to keeping reloading (still not sure why), without it works.
@dugan I agree. I was also looking for the token on the server side and in principle that’s true;
When you GET the login page RStudio server sets the csrf-token in the cookie which will be used for the POST request. But, when it gets the request, RStudio just checks that the csfr-token you use is the same present in the cookie (and not if it was generated by the server).
At the moment this solution is simpler but in case RStudio changes the check we may need to “GET” the login page in the “script” section and parse the cookie to get the csrf-token generated by RStudio. The token is generated for the “session”, so it should work. But, as said, for the moment it seems not needed.
Apologies for this issue. There was a bug that got fixed in the 2.0 release where URLs without a trailing / did not redirect to the backend correctly. So this should at least alleviate that 1 particular issue.