kstm-su / isctsc2021Summer

ictsc2021夏の陣チームkstm用
0 stars 0 forks source link

13 サーバ天気予報 150pt #6

Open passerby-1 opened 3 years ago

passerby-1 commented 3 years ago

概要

スクリーンショット (789) とある会社に勤めている、K君はサーバのお天気管理システムを開発しています。しかし、気温と湿度の情報を取得・送信することができません。原因を究明して取得・送信出来るようにして下さい。

前提条件

初期状態

終了状態

接続情報

VM名 ホスト名 ユーザ パスワード
prob4-client(踏み台兼VNC) 192.168.4.1 user ictsc2021
prob4-proxy 192.168.4.100 user ictsc2021
prob4-web(アクセス不可) 192.168.4.101 x x
prob4-api 192.168.4.102 user ictsc2021

prob4-client の TCP 5901 ポートにてVNCサーバが起動しています。手元のPCからSSHポートフォワード経由でVNC接続を行うことができます。

ssh user@チームの踏み台サーバ -L 5901:192.168.4.1:5901

上記コマンドを実行後、任意のVNCクライアントより localhost:5901 に接続してください。 VNC接続時のパスワードは ictsc2021 です。

oyuyu-dev commented 3 years ago

プロキシサーバのnginx.conf

user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;

events {
        worker_connections 768;
        # multi_accept on;
}

http {

        ##
        # Basic Settings
        ##

        sendfile on;
        tcp_nopush on;
        tcp_nodelay on;
        keepalive_timeout 65;
        types_hash_max_size 2048;
        # server_tokens off;

        # server_names_hash_bucket_size 64;
        # server_name_in_redirect off;

        include /etc/nginx/mime.types;
        default_type application/octet-stream;

        ##
        # SSL Settings
        ##

        ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE
        ssl_prefer_server_ciphers on;

        ##
        # Logging Settings
        ##

        access_log /var/log/nginx/access.log;
        error_log /var/log/nginx/error.log;

        ##
        # Gzip Settings
        ##

        gzip on;

        # gzip_vary on;
        # gzip_proxied any;
        # gzip_comp_level 6;
        # gzip_buffers 16 8k;
        # gzip_http_version 1.1;
        # gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

        ##
        # Virtual Host Configs
        ##

        include /etc/nginx/conf.d/*.conf;
        include /etc/nginx/sites-enabled/*;
        server {
          listen 80;
          server_name web.test;

          location / {
            proxy_pass http://192.168.4.101;
          }
        }

        server {
          listen 80;
          server_name api.test;

          location / {
            proxy_pass http://192.168.4.102:3000;

            add_header Access-Control-Allow-Origin '*';
            add_header Access-Control-Allow-Methods 'GET';
            add_header Access-Control-Allow-Headers 'Accept';
          }
        }
}

#mail {
#       # See sample authentication script at:
#       # http://wiki.nginx.org/ImapAuthenticateWithApachePhpScript
#
#       # auth_http localhost/auth.php;
#       # pop3_capabilities "TOP" "USER";
#       # imap_capabilities "IMAP4rev1" "UIDPLUS";
#
#       server {
#               listen     localhost:110;
#               protocol   pop3;
#               proxy      on;
#       }
#
#       server {
#               listen     localhost:143;
#               protocol   imap;
#               proxy      on;
#       }
#}
oyuyu-dev commented 3 years ago

apiサーバーのserver.js

const express = require('express');
const cors = require('cors');
const bodyParser = require('body-parser');
const app = express();

//app.use(cors());

app.use(bodyParser.urlencoded({
          extended: false
}));

app.use(bodyParser.json());

let temperature = 20;
let humidity = 21;

app.get('/', (req, res) => {
          res.status(200).send(`{"temperature": ${temperature}, "humidity": ${humidity}}`);
});

app.post('/', (req, res) => {
          console.log(req.body);
          temperature = req.body['temperature'];
          humidity = req.body['humidity'];
          res.status(200);
});

app.listen(3000, () => {
          console.log('server is listening on port 3000...')
oyuyu-dev commented 3 years ago

apiサーバで

curl localhost:3000

{"temperature": 20, "humidity": 21}


proxサーバで

curl http://192.168.4.102:3000;

{"temperature": 20, "humidity": 21}


踏み台サーバで curl http://192.168.4.102:3000;

{"temperature": 20, "humidity": 21}

curl http://api.test;

{"temperature": 20, "humidity": 21}

user@client:~$ curl http://api.test;

{"temperature": 20, "humidity": 21}

user@client:~$ curl http://web.test;

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
<script src="index.js" type="module"></script>

<h1>とあるサーバ室内お天気情報</h1>
<p id="temperature_value">気温:</p>
<p id="humidity_value">湿度:</p>

<div>
    <h4>天気を取得</h4>
    <button id="get">取得</button>
</div>
<div>
    <h4>天気を送信</h4>
    <div>
        <label for="temperature">気温</label>
        <input type="text" name="name" id="temperature" required>
    </div>
    <div>
        <label for="humidity">湿度</label>
        <input type="text" name="name" id="humidity" required>
    </div>
<button id="post">送信</button>
</div>
</body>
</html>
oyuyu-dev commented 3 years ago

お世話になっております。チームkstmです。

この問題では、webサーバとapiサーバを分けていますが、フロントのjsからapiサーバを呼び出す際にCROSヘッダーが正しく設定されていないため、ブラウザにブロックされるということが原因でした。

そのため、リバースプロキシであるnginxの設定ファイルを書き換えることで対応可能です。以下に手順をしめします。

手順

  1. 踏み台サーバにSSHでログイン

    ssh user@192.168.4.1
  2. プロキシサーバにSSHでログイン

    ssh user@192.168.4.100
  3. /etc/nginx/nginx.confを書き換える。 api.test;の設定部分のAccess-Control-Allow-HeadersContent-Typeを追加

一部分を切り出し

server {
          listen 80;
          server_name api.test;

          location / {
            proxy_pass http://192.168.4.102:3000;

            add_header Access-Control-Allow-Origin '*';
            add_header Access-Control-Allow-Methods 'GET';
            add_header Access-Control-Allow-Headers 'Accept,Content-Type';
          }
        }
  1. nginx を再起動