我的RoR应用程序需要访问远程数据库(FWIW它在rds.amazonaws.com上托管的mysql)。访问它的唯一方法是通过SSH隧道。
我已经在本地计算机上测试了访问权限。我通过以下方式设置隧道:
ssh -f -N -L 3307:longname.rds.amazonaws.com:3306 remote_user@remote_host.com
(但请参阅https://stackoverflow.com/a/27305457/558639了解我实际上是如何做到的)。无论如何,我需要在Heroku上安装一个SSH密钥对(私有和公共部分),以便工作。
但是,我在这里的陌生领域。我可以编写一个脚本,该脚本在安装密钥的Heroku会话开始时启动。什么是正确的方法来实现这一点,而不是不必要地暴露私钥?答案 0 :(得分:0)
这就是我想出的。 (有关详细说明,请参阅SSH tunneling from Heroku。)
heroku config:set NAME1=value1 NAME2=value2 etc...
.profile.d/web-setup.sh
。请注意,根据https://devcenter.heroku.com/articles/profiled,.profile.d
目录中的任何文件都将在首次设置dyno时运行。注意:这样,私有SSH密钥 only 在heroku环境中显示为配置变量。由于其他敏感信息保留在那里,我认为这是一种相对安全的方法。
.profile.d/web-setup.sh
文件包含:
# file=.profile.d/web-setup.sh
# create keypair files on this dyno
echo $0: creating public and private key files
mkdir -p ${HOME}/.ssh
echo "${PUBLIC_KEY}" > ${HOME}/.ssh/heroku_id_rsa.pub
chmod 644 ${HOME}/.ssh/heroku_id_rsa.pub
# note the use of double quotes to preserve newlines!
echo "${PRIVATE_KEY}" > ${HOME}/.ssh/heroku_id_rsa
chmod 600 ${HOME}/.ssh/heroku_id_rsa
# You may need to preload known-hosts here. See
# https://stackoverflow.com/questions/21575582/ssh-tunneling-from-heroku/27361295#27361295
# on how to do that.
# open a tunnel if not already running
SSH_CMD="ssh -f -i ${HOME}/.ssh/heroku_id_rsa -N -L ${LOCAL_PORT}:${REMOTE_MYSQL_HOST}:${MYSQL_PORT} ${REMOTE_USER}@${REMOTE_SITE}"
PID=`pgrep -f "${SSH_CMD}"`
if [ $PID ] ; then
echo $0: tunnel already running on ${PID}
else
echo $0 launching tunnel
$SSH_CMD
fi