- 投稿日:2022-03-22T21:19:24+09:00
Vuls動作検証 - MySQL
目的 MySQLのバージョン情報をもとに脆弱性情報を取得してみる。 方法 CPEを確認していくつかピックアップ Google NVD - Search vulsio/go-cpe-dictionary: Build a local copy of CPE(Common Platform Enumeration) CPE情報をもとに脆弱性情報を取得 NVD - Search vulsio/go-cve-dictionary: Build a local copy of CVE (NVD and Japanese JVN). Server mode for easy querying. 8.0系 NVD - Detail - cpe:2.3oracle:mysql:8.0.0:*:*:*:*:*:*:* Version 2.3: cpe:2.3:a:oracle:mysql:8.0.0:*:*:*:*:*:*:* Version 2.2: cpe:/a:oracle:mysql:8.0.0 Version NVD CVEs go-cve-dictionary 8.0.0 NVD - Results 513 513 8.0.10 NVD - Results 513 513 8.0.20 NVD - Results 274 274 8.0.25 NVD - Results 119 119 8.0.26 NVD - Results 110 110 8.0.27 NVD - Results 69 69 5.7系 NVD - Detail - cpe:2.3oracle:mysql:5.7.0:*:*:*:-:*:*:* Version 2.3: cpe:2.3:a:oracle:mysql:5.7.0:*:*:*:-:*:*:* Version 2.2: cpe:/a:oracle:mysql:5.7.0::~~-~~~ NVD - Detail - cpe:2.3oracle:mysql:5.7.0:*:*:*:community:*:*:* Version 2.3: cpe:2.3:a:oracle:mysql:5.7.0:*:*:*:community:*:*:* Version 2.2: cpe:/a:oracle:mysql:5.7.0::~~community~~~ Version NVD CVEs go-cve-dictionary 5.7.0 NVD - Results 470 470 5.7.10 NVD - Results 463 463 5.7.20 NVD - Results 306 306 5.7.30 NVD - Results 146 146 5.7.36 NVD - Results 100 100 確認 バージョンが上がるに従い検知数が減っているので概ね妥当に見える 5.7.36 で NVD - CVE-2020-14846 が対象に表示されるが、8系の影響のみ記載があり5.7系の影響は記載されていない。 Oracle Critical Patch Update Advisory - October 2020 を見ると8.0系についての影響のみ記載されている。これは5.6系と5.7系には影響がないことを意図しているような気もするが、よくわからない。 CVE-2020-14846 | Ubuntu を見ると5.7のところにNot vulnerable (8.0 only)と記載されているので5.7系には影響がなかったように見えるけど、どうなんだろう。
- 投稿日:2022-03-22T19:11:34+09:00
Go + MySQL + React のDocker開発環境を作成する
はじめに GoとMySQLとReact(&TypeScript)を使ったポートフォリオ作成をしようと思い、最初に勉強も兼ねてDocker開発環境を作成しました。 そこでQiitaやZennなどで書かれている記事を参考にしていましたが、最終的に他の方とは違う構成になったので自分も記事を執筆しようと思いました。 作成したもの ディレクトリ構成 . ├── README.md ├── db │ ├── data │ └── my.cnf ├── docker-compose.yml ├── go-app │ ├── Dockerfile │ └── main.go ├── react-ts-app │ ├── .dockerignore │ ├── Dockerfile │ ├── README.md │ ├── node_modules │ ├── package-lock.json │ ├── package.json │ ├── public │ ├── src │ └── tsconfig.json └── variables.env Dockerfile(go-app) FROM golang:latest WORKDIR /app/go COPY ./ ./ ENTRYPOINT [ "go", "run", "main.go" ] Dockerfile(react-ts-app) FROM node:17.7.2 WORKDIR /app/react-ts COPY package*.json ./ RUN yarn install COPY . . ENTRYPOINT [ "npm", "start" ] dockerignoreファイル(react-ts-app) node_modules npm-debug.log yarn-error.log docker-compose.yml version: '3' services: react-ts: build: ./react-ts-app ports: - '3000:3000' tty: true stdin_open: true go: build: ./go-app ports: - '8000:8000' tty: true stdin_open: true db: image: mysql:8.0 volumes: - './db/data:/var/lib/mysql' - './db/my.cnf:/etc/mysql/conf.d/my.cnf' # MYSQL_ROOT_PASSWORDのみをenvファイルで設定 env_file: - variables.env ports: - '3306:3306' my.cnf [mysqld] character-set-server=utf8mb4 collation-server=utf8mb4_unicode_ci [client] default-character-set=utf8mb4 解説 Dockerfileは、docker-composeを使わなくても単体で動作することが可能だよねっていう状態を意識しました。 また、docker-composeはあくまでコンテナを立ち上げるのを楽にするためのものだと意識しました。 Dockerfile ENTRYPOINTを指定していることで、docker-composeをupした瞬間にdb・go・react-tsの3つのコンテナが起動&サーバーも起動するようになっています。 COPY句によってDockerfile自体もイメージ内にコピーされてしまいますが、イメージサイズへの影響が小さい・dockerignoreファイルを作成してもビルドにかかる時間は変わらないと判断し、許容しています。 dockerignoreファイルによるビルド時間への影響は下記のサイトが参考になります。 dockerignore(React用) node_modules、npm-debug.log、yarn-error.log の3つを指定しています。 これによってローカルモジュール・デバッグログ・エラーログがDockerイメージにコピーされないようにします。 node_modulesはパッケージがインストールされるディレクトリです。必要なパッケージはソースコードによって異なるため、node_modulesをイメージ内にコピーする必要はないと言えます。 また、node_modules内に多くのパッケージをインストールしている場合、イメージをビルドするときに多くの時間を要します。そのため、node_modules は dockerignoreファイルに登録することが基本となっています。 node_modules のコピーはしませんがコンテナ内でもパッケージは必要になります。ReactのDockerfileでは package.json と package-lock.json をコピーし、yarn install を行うことで、コンテナ使用者が必要なパッケージのみをインストールするようにしています。 Go FROM でイメージを取得するときに、golangにするか、ubuntuのようなOSイメージにするか、golang:<version>-alpineにするかで迷いました。 この中で一番設定ミスが起こりづらそうだと感じたgolangにしました。 dockerの知識量的にOSイメージからGoの環境を整えるのはハードルが高そう。また、alpineはGo projectに公式サポートされていないとDockerhubに書いてあるといった理由で、この2つは選択肢から外しました。 ENTRYPOINT によって、コンテナが立ち上がるとともに go run main.go でサーバーも立ち上がるようにしています。 以下、main.goのコードです。 main.go package main import ( "fmt" "net/http" ) func main() { http.HandleFunc("/", echoHello) http.ListenAndServe(":8000", nil) } func echoHello(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "<h1>Hello World</h1>") } React nodeイメージのDockerfileを見ると、デフォルトでyarnが入っていることがわかります。 なので、yarnをわざわざインストールする必要はありません。 また、Dockerfileやcomposeにcreat-react-appの記述もされている方がいますが、コンテナを起動するたびに新規のプロジェクト作成するのは時間がかかりそうだと感じたので僕は書きませんでした。 あくまでソースコードはホスト上にあり、コンテナへそれらをコピーすることで正常に動くようにしたいと思いました。 次に最も重要な部分ですが、ReactのDockerfileではビルド時間の短縮のためにCOPY句を2つ使っています。 COPY package*.json ./ RUN yarn install COPY . . dockerにはレイヤー構造とキャッシュという概念があり、これを活用することでイメージのビルド時間を短縮できます。 レイヤーとキャッシュについては解説すると長くなるので、ここでは割愛させていただきます。 Reactの開発では頻繁にソースコードを変えると思います。 もし yarn install の前に COPY . . を行うと、ソースコードが変更されるたびにパッケージをインストールし直すことになります。 パッケージを追加・変更していなくても毎回この処理が行われ、多くの時間が費やされてしまいます。 COPY package*.json ./ と yarn install を先に行なっていればレイヤーキャッシュが使用され、ビルドの時間を大幅に節約できます。 以上の理由から、COPYを2回使うようにしました。 この記述方法は、こちらのサイトを参考にしました。 MySQL MYSQL_ROOT_PASSWORDを設定しなければエラーが出ます。 共有をしないのであればcompose上に直接設定してもいいですが、僕はgithubを通じて共有しようと考えていたのでenvファイルを使いました。 MySQLはローカルホスト上ではmysql.server startを使って起動する必要があるかと思いますが、このコンテナ上ではそれが必要ありません。コンテナが立ち上がるとともにDBサーバーも立ち上がります。 my.cnfファイルを用意していありますが、ここでは文字化けを防ぐための設定しかしていません。 もしかしたら他にももっと設定した方がいいものもあるかもしれませんが、沼にハマりそうなのでやめました。 最後に 人によって書き方が違って正しい情報を入手しづらく、結構時間がかかってしまいました。 もちろん僕が書いたものも正しいとは言い切れないので、これから更に知識をアップデートしていきたいなと思います。
- 投稿日:2022-03-22T16:47:49+09:00
MySQL with Python connector
MySQL 記事の背景 MySQLに関する記事は多いのですが、途中まで躓いているものも多い。 本記事は、Windowsに限定してインストール、初期設定、データベース作成 そしてPythonからデータベースへのアクセスまで網羅します。 1.install MySQLダウンロードサイト https://dev.mysql.com/downloads/installer/ ログインについては、スキップする 画面左下の「No thanks, just start my download.」からダウンロードする。 2.インストール設定 Custom ☑MySQL Server ☑MySQL Shell ☑Connector/Pythonを選ぶ Type & networking ☑Development Computerを選択 ☑TCP/IP Port:3306 ☑X Protocol Port:33060 ☑Open Windows Firewall port for network access 認証設定 ☑Use strong password Encryption for Authentication Use Legacy Authentication Method 3.認証関連 ☑ルートパスワード入力 ☑ユーザ名追加 User Name: Host:locahost Role:DB Admin 4.MySQL 基本コマンド ☑データベースを表示する show databases; ☑データベースを作成する CREATE DATABASE sample_db; ☑データベースを選択する use sample_db; ☑テーブルを表示する SHOW TABLES; 4.Python connector pip install mysql-connector-python pip list | grep mysql mysql-connector-python 8.0.28 5. ソースサンプル
- 投稿日:2022-03-22T12:29:23+09:00
MySQLのSELECT文でカラムの指定とWHEREを使った取得条件の指定方法
データベース多少使っていたものの余り意味を理解していなかったほぼド素です。 前回MySQLでデータベース(以下DB)を作成したので今回はSELECT文についてEnvaderの環境を用いてデータの操作を学んでいきます。 SELECT文について SELECT文はSQL文のうちDML(Data Manipulation Language)データ操作言語の一つです。 読んで字のごとくですがDBからデータを取得してくる際に使用します。 SELECT カラム名 FROM テーブル名; SQL文お約束の末尾に;(セミコロン)を忘れないようにしましょう。 主なDML SELECT データ取得 UPDATE データ更新 DELETE データ削除 INSERT データ挿入 操作方法1. カラムの指定 *(アスタリスク)を使用して指定したテーブル内のすべてのカラムを取ってくる場合。 SELECT * FROM テーブル名; 複数のカラムを取得する場合はカラム名を,(カンマ)で区切ります。 SELECT name, mail, salary FROM テーブル名; 操作方法2. WHEREを使った取得条件の指定 WHERE 絞り込み条件とすることで該当するデータを取得できます。 SELECT カラム名 FROM テーブル名 WHERE 絞り込み条件; # 社員テーブルから長宗我部さんを絞り込んでみます SELECT * FROM employee WHERE name="長宗我部"; 比較演算子を使って絞り込むことができます。 SELECT * FROM employee WHERE salary<=300000; 比較演算子 使用用途 = ~と等しい < ~より小さい > ~より大きい <= ~以下 >= ~以上 <>または != ~と等しくない 使ってみた ここまでしっかり理解できているかどうか、MySQL SELECTの基本①の演習問題2を解いてみます。 まずはDBに接続しPasswordを入力します。 mysql>が表示されたらuseコマンドを使用してDBを指定します。 use food_app userテーブルに存在するレコードの中でidが5の人のemailアドレスを答えなさい。 とのことなのでカラム名をemail、テーブル名をuser、条件をid=5とした以下のSELECT文を入力。 select email from user where id=5; +----------------------+ | email | +----------------------+ | horikawa@example.com | +----------------------+ 1 row in set (0.00 sec) SELECTやWHEREを小文字で入力することもできます。現場の状況にあった使い方をしましょう。 このように条件に合うメールアドレスを取得できました。 メールをコピペして解答欄に貼り付け提出し、無事正解となりました。 学んだこと とりあえずタイトル通りのことは一通りできました。 単純なコマンドですが何回も繰り返し打たないとド忘れしそうな気がします。 次回学ぶこと SELECT文後半となるLIMITと並べ替えを学びます。 参考にした資料
- 投稿日:2022-03-22T10:52:03+09:00
MySQLの整数型に関して
初めに MySQLの整数型に関して勉強した内容を投稿する。 環境 ■ MySQLのバージョン 5.7.35 ■ 今回使用するテーブル設計 CREATE TABLE `new_table` ( `id` tinyint(1) NOT NULL, `TINYINT` tinyint(11) DEFAULT NULL, `TINYINT_UNSIGNED` tinyint(11) unsigned DEFAULT NULL, `TINYINT_ZEROFILL` tinyint(5) unsigned zerofill DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 ※既にid 1 にレコードを挿入した状態。 整数型の種類 MySQLの整数型には「TINYINT型」「SMALLINT型」「MEDIUMINT型」「INT型」「BIGINT型」がある。 それぞれ、ストレージ、最小値、最大値が異なっているので格納する値によって使い分ける必要がある。 詳細は下記を参照。 MySQL公式 TINYINT型 今回は、例としてTINYINT型を使用する。 TINYINT型のストレージは1バイト、最小値は(-128/0)最大値は(127/255)である。 ※値は(符号付き/符号なし)で分けている。 最大値を更新 冒頭に記載したテーブルのTINYINT型に、最大値(127/255)を更新してみると、正常に意図した値が格納される。 UPDATE `test_schema`.`new_table` SET `TINYINT`= 128 WHERE `id`='1'; UPDATE `test_schema`.`new_table` SET `TINYINT_UNSIGNED`= 255 WHERE `id`='1'; 次に最大値を超える値を更新しようとする。 UPDATE `test_schema`.`new_table` SET `TINYINT`= 129 WHERE `id`='1'; UPDATE `test_schema`.`new_table` SET `TINYINT_UNSIGNED`= 256 WHERE `id`='1'; 値が最大値のままになっていることが分かる。 更新前の値が最大値でなくとも、最大値を超えた値を更新しようとすると最大値に更新されるようだ。 TINYINT型以外も同じ挙動を確認した。 また、最小値より小さい値を更新しようとすると、最大値と同じように最小値で更新されることが分かった。 インサート文でも同じように最大値を超えた値を挿入しようとすると、最大値で値が格納されている。 INSERT INTO `test_schema`.`new_table` (`id`, `TINYINT`, `TINYINT_UNSIGNED`) VALUES ('2', 129, 256); ただし以下のメッセージが返却される。 1 row(s) affected, 2 warning(s): 1264 Out of range value for column 'TINYINT' at row 1 1264 Out of range value for column 'TINYINT_UNSIGNED' at row 1 ()内の桁数に関して ()内の桁数はzerofillを指定した場合に有効となる。 ※MySQLでは、zerofillを指定すると、自動的にUNSIGNED 属性を追加する。 冒頭のテーブル設計で記載した「TINYINT_ZEROFILL」カラムを使用する。 1を更新してみる。 UPDATE `test_schema`.`new_table` SET `TINYINT_ZEROFILL`=1 WHERE `id`='1'; ()内の数値は5だったため、0が1の前に4つ付与されていることが分かる。 まとめ 整数型を使用する際に、基本的には使用するストレージの容量が小さい型から優先的に使用するべきだと考える。 そのため、基本的な優先順位は以下になる。 1.TINYINT型 2.SMALLINT型 3.MEDIUMINT型 4. INT型 5. BIGINT型 また、負の数を使用しないのであれば基本的にunsigned属性を付与して、よりストレージの容量が小さい型を選択すべきだと考えられる。
- 投稿日:2022-03-22T10:26:57+09:00
【備忘録】プライマリキー(主キー)について
プライマリキー(主キー)とは プライマリーキー(主キー)とは作成したテーブルの中の1つまたは複数のカラムの組み合わせに対して設定するもので、 テーブルに格納されているデータを識別するための目印のようなものです。 テーブルには多くのデータが含まれており、 1つ1つのデータには複数のカラムの値が格納されています。 格納されたすべてのデータの中から1つのデータを特定したいときに、 1つまたは複数のカラムの値を検索してデータを特定しますが、 その時に最も適したカラムに設定されるのがプライマリーキーです。 カラムにプライマリーキー制約を設定すると、 カラムには他のデータの値を重複することのない値しか格納することができなくなります。 また NULL も格納することができません。 その結果、プライマリーキー制約が設定されたカラムの値を検索することで、 テーブルの中でただ一つのデータを特定することができます。 参考: https://www.dbonline.jp/mysql/table/index8.html#:~:text=%E3%83%97%E3%83%A9%E3%82%A4%E3%83%9E%E3%83%AA%E3%83%BC%E3%82%AD%E3%83%BC(%E4%B8%BB%E3%82%AD%E3%83%BC)%E3%81%A8,%E3%81%AE%E3%82%88%E3%81%86%E3%81%AA%E3%82%82%E3%81%AE%E3%81%A7%E3%81%99%E3%80%82
- 投稿日:2022-03-22T05:38:22+09:00
【Docker】DBの起動完了を待ってから他のサービスを起動する方法
はじめに 本記事は、プログラミング初学者、学習を進めていて疑問に思った点について調べた結果を備忘録も兼ねてまとめたものです。 そのため、記事の内容に誤りが含まれている可能性があります。ご容赦ください。 間違いを見つけた方は、お手数ですが、ご指摘いただけますと幸いです。 DBの起動完了を待ってから他のサービスを起動する方法 docker-compose.ymlのdepends_on/conditonを設定する方法 以下のようにdepends_onにconditionservice_healthyを設定し、dbのhealthcheckにtestを設定することでDBの起動完了後に他のサービスを起動させることができます。 testのインターバルがデフォルトでは30秒ほどのようでヘルスチェックに時間がかかるため、intarvalを1sに設定しています。 docker-compose.yml version: '${COMPOSE_VER}' services: db: platform: linux/x86_64 image: mysql:${DB_IMAGE_TAG} command: --default-authentication-plugin=mysql_native_password && bash -c "chmod +x /docker-entrypoint-initdb.d/00_grant.sh" healthcheck: test: mysqladmin ping -h db -u$${MYSQL_USER} -p$${MYSQL_PASSWORD} interval: 1s volumes: - mysql_data:/var/lib/mysql - ${MY_CNF_PATH}:/etc/mysql/conf.d/my.cnf - ${INITDB_PATH}:/docker-entrypoint-initdb.d env_file: - ${DB_ENV_FILE_PATH} ports: - "${DB_PORT}:3306" api: build: context: . dockerfile: ./docker/api/Dockerfile command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'" volumes: - .:/myapp environment: RAILS_ENV: ${APP_ENV} ports: - "${API_PORT}:3000" depends_on: db: condition: service_healthy volumes: mysql_data: