Я хочу подключиться к своему экземпляру ec2, используя aws ssm sdk для ржавчины. Как лучше всего создать интерактивный сеанс терминала? Вот следующий код, который я использую для создания сеанса ssm:
pub async fn create_ssh_session(&self, instance_id: &str) -> Result<()> {
let output = self
.client
.start_session()
.document_name("SSM-SessionManagerRunShell")
.target(instance_id)
.send()
.await?;
let wss_url = output.stream_url().unwrap();
let (mut ws_stream, response) = tokio_tungstenite::connect_async(Url::parse(wss_url)?).await?;
// Print response to confirm successful connection
println!("Connected: {}", response.status());
let output = self
.client
.terminate_session()
.session_id(output.session_id().unwrap())
.send()
.await?;
// println!("{:#?}", output);
Ok(())
}
Я попытался подключиться к URL-адресу WSS с помощью Tokio Tungstenite, но не уверен, что это лучший способ.
Обновлено: когда я пытаюсь подключиться, мне выдается код состояния 101 (протоколы переключения), что это значит, и после запуска сеанса с ssm я получаю wss_url и токен. Согласно документации, там говорится, что токен используется для аутентификации соединения с управляемым узлом. Я хочу знать, как это сделать при создании потока.
@user2407038 user2407038 Я хочу знать, как правильно создать этот сеанс и присоединиться к нему, а также как я могу создать опыт, подобный ssh. Я обновил вопрос, добавив более подробную информацию!
(вот информация, которую я собрал при создании инструментов с помощью ssm-agent start-session
API)
Согласно документации awscli ssm start-session
, для вашей ОС требуется sessionmanager-plugin
.
(ПРИМЕЧАНИЕ: awscli
использует тот же API, что и aws SDK)
ДОКУМЕНТЫ: https://docs.aws.amazon.com/cli/latest/reference/ssm/start-session.html#description
sessionmanager-plugin
— это набор golang
кода, который обрабатывает потоки и протокол веб-сокета (IE: консоль, переадресация портов и т. д.).
https://github.com/aws/session-manager-plugin
Приведенный выше код не упакован как модуль golang
, вы можете использовать его в своем проекте в качестве библиотеки для создания двоичных файлов для ваших настроек.
Вместо того, чтобы напрямую общаться с агентом ssm в экземпляре, я решил, что будет проще взаимодействовать с session-manager-plugin
, как предложил @john. Я не смог найти достоверной информации об использовании плагина диспетчера сеансов из командной строки, и я задал этот вопрос здесь.
вот основной рабочий процесс создания сеанса с использованием aws sdk для ржавчины с помощью session-manager-plugin
:
pub async fn create_ssh_session(&self, instance_id: &str) -> Result<()> {
// start session get session_id, token_value and stream_url
let output = self
.client
.start_session()
.document_name("SSM-SessionManagerRunShell")
.target(instance_id)
.send()
.await?;
// create ssm plugin json message
let response = ResponseJson {
SessionId: output.session_id().unwrap().to_string(),
TokenValue: output.token_value().unwrap().to_string(), // Assuming `token` is defined elsewhere
StreamUrl: output.stream_url().unwrap().to_string(),
};
// commenting code for reference
// let template =r#"{"Target" : "{instance_id}","DocumentName": "AWS-StartPortForwardingSession","Parameters" : {"portNumber": [22],"localPortNumber": [3232] }}"#;
// let ssm_plugin_document = json!(template.replace("{instance_id}", instance_id.into()));
// let plugin_string = serde_json::to_string(&ssm_plugin_document)?;
let response_string = serde_json::to_string(&response)?;
let mut session_manager_plugin = Command::new("session-manager-plugin");
let run_command_output = session_manager_plugin
.args([
response_string,
"ap-southeast-2".into(),
"StartSession".into(),
"https://ssm.ap-southeast-2.amazonaws.com/".into(),
])
.spawn()?;
let result = run_command_output.wait_with_output()?;
let output = self
.client
.terminate_session()
.session_id(output.session_id().unwrap())
.send()
.await?;
Ok(())
}
Я просто создаю session-manager-plugin
как процесс с правильными аргументами, используя документ SSM-SessionManagerRunShell
.
Что вы подразумеваете под «лучшим способом»? Не удается ли этому коду установить соединение, и если да, то в чем заключается ошибка соединения?