なんかかきたい

プログラミングなどの個人的なメモやサークル「ゆきいろパラソル」の情報を載せてます

Jenkins Configrations as Code と Groovy サンドボックス

サマリー

  • JenkinsにはGroovyを実行する機能があるが、任意のコードの実行を防ぐため、実行できるメソッドを制限する Groovy Sandbox という仕組みがある。
  • Groovy Sandbox を有効にするには、Authorize Project plugin で特定のユーザ権限で動作させる必要がある
    • cronのように自動起動するジョブは SYSTEM として実行され Sandbox で実行できないため
  • Sandboxで実行する場合、許可するメソッドを事前に設定しておき、意図しないメソッドの呼び出しに気付けるようにする運用になる
  • JCasC には Authorize Project plugin と Script Security Plugin の scriptApproval を設定する方法がない
  • とはいえ、この設定は一度設定したら変更することもないはずなので、Jenkins起動前に事前にXMLを入れておけばいいよという話

Authorize Project plugin

  • プロジェクトごとに特定のユーザの権限でジョブを実行させる設定ができるようになるプラグイン
    • QueueItemAuthenticator が追加され、各プロジェクトで実行ユーザの指定ができる
    • cronのように自動実行されるジョブは SYSTEM として実行される
    • SYSTEM で動くと Sandbox 実行されないが、このプラグインで実行ユーザを指定すると Sandbox の対象になる
    • Groovy SandBox を使う場合、このプラグインと組み合わせることが重要になる
  • このプラグインの設定を JCasC で行うことができない (今後対応されるかもしれないが)
    • 現状最も簡単な設定方法はJenkins起動前に JENKINS_HOME/jenkins.security.QueueItemAuthenticatorConfiguration.xml を作っておく方法
    • DockerイメージのJenkinsを使う場合も JENKINS_HOME は外部のボリュームをマウントすることが多いので、そちらのおいておくか、エントリーポイントのスクリプト内でコピーする

設定例

<?xml version='1.1' encoding='UTF-8'?>
<jenkins.security.QueueItemAuthenticatorConfiguration>
  <authenticators>
    <org.jenkinsci.plugins.authorizeproject.ProjectQueueItemAuthenticator plugin="authorize-project@1.3.0">
      <strategyEnabledMap>
        <entry>
          <string>org.jenkinsci.plugins.authorizeproject.strategy.SpecificUsersAuthorizationStrategy</string>
          <boolean>true</boolean>
        </entry>
        <entry>
          <string>org.jenkinsci.plugins.authorizeproject.strategy.TriggeringUsersAuthorizationStrategy</string>
          <boolean>false</boolean>
        </entry>
        <entry>
          <string>org.jenkinsci.plugins.authorizeproject.strategy.SystemAuthorizationStrategy</string>
          <boolean>false</boolean>
        </entry>
        <entry>
          <string>org.jenkinsci.plugins.authorizeproject.strategy.AnonymousAuthorizationStrategy</string>
          <boolean>false</boolean>
        </entry>
      </strategyEnabledMap>
    </org.jenkinsci.plugins.authorizeproject.ProjectQueueItemAuthenticator>
  </authenticators>
</jenkins.security.QueueItemAuthenticatorConfiguration>

Script Security Plugin

  • Jenkinsで実行されるGroovyスクリプトを任意実行できないように呼び出せるメソッドの制限ができるプラグイン
  • Job DSL plugin などでGroovyを実行する際にも適用されるため、このプラグインを入れている場合、Groovy Sandbox で実行する必要が出てくる
  • 許可するメソッドは scriptApproval のWebUI上で設定できるが、Administrator権限が必要。
    • Administrator権限を持っているとJenkinsを任意に操作できるため、scriptApprovalのためだけにAdministrator権限を与えたくないと思う
  • scriptApprovalは単なるXMLの設定であり、事前にどのメソッドの呼び出しを許すかわかっているのであれば、同じくJENKINS_HOMEにおいておけば良い。
<?xml version='1.1' encoding='UTF-8'?>
<scriptApproval plugin="script-security@1.66">
  <approvedScriptHashes/>
  <approvedSignatures>
    <string>staticField groovy.io.FileType DIRECTORIES</string>
  </approvedSignatures>
  <aclApprovedSignatures>
    <string>method groovy.lang.GroovyObject getProperty java.lang.String</string>
    <string>method groovy.lang.GroovyObject invokeMethod java.lang.String java.lang.Object</string>
  </aclApprovedSignatures>
  <approvedClasspathEntries/>
  <pendingScripts/>
  <pendingSignatures/>
  <pendingClasspathEntries/>
</scriptApproval>

Qiitaを退会しました

昔のQiitaは技術情報を共有する場でしたが、今では技術情報のノイズとなっている惨状。

Googleの検索でも -qiita で検索することが多くなっていて、そういえばQiitaって開いてないなという状況が長く続いていました。

事実上使っていないサービスですが、アカウントを削除するのも面倒で残しておりました。 しかし昨日、閲覧記事の傾向を表示するという機能が追加されたと聞いて、アカウントの削除を決めました。

Qiita、読んだ記事の傾向を合意無しに表示して炎上 批判受け機能停止中

https://www.itmedia.co.jp/news/articles/2003/26/news087.html

嫌なら使わなくてよいという潔い判断です。自分の記事の質もとても良いものとはいえず、Qiitaのディスクスペースを圧迫するだけと思いましたので綺麗に消すことにしました。 一部の有用な情報はgistなどに置くかもしれません。自分が見直すメモ書き程度に。

昔は良かったな...というお気持ちの表明です。

AWSでAZ障害が起きたのでなるべく影響を受けない構成の考えを書いておく

AZ障害は受け入れるしかないクラウド時代のインフラ

ただの日記。 今日の昼、AWSを利用している人たちは大変だったところもあると思う。 AZの一つが丸々機能しなくなる大きなAWSの障害があり、AWSを利用して運用されていたサービスは多かれ少なかれ影響を受けることになった。

完全に雰囲気で書いてしまうが、今回のAZ障害で影響を受けたサービスは思ったより多かったように感じる。 というのもAWSではアベイラビリティーゾーンの障害は発生するものと考え、本番運用するのであれば、マルチAZ構成を取るのがベストプラクティスとされているので、 マルチAZ構成を取っていれば影響なんてないんじゃないの普通、と思ってしまうと思う。 インフラ屋さんでもそう思ってしまうし、インフラ屋さん以外ならなおさらなんで重くなるのかわからないと思う。

幸い自分の運用しているサービスでは影響が軽微だったので、完全に想像にはなってしまうけど、起こりがちなケースを考えてみる。

続きを読む

rsyncでpigzするやつ v2

普段よく使っているのでリモートからローカルにコピーする場合に使えるように機能拡張した。

ほとんど同じコードなのに共通化できなくて辛い。ifで分岐して二つのシェルスクリプトを一個にしたような作りがイケてないが使い勝手はよい。

細かい話だと rsync の出力がOSXLinuxで微妙に違うとかそういうところも吸収した。代わりに awk が必要になった。リストの取得に ./ から空行までをawkで出力する。 tailtac は消えた。

gist.github.com

便利

nginxの設定をrspecでテストする

前略。やや複雑な nginx.conf があります。

nginx の設定はたまに変更する必要がありますが、それなりに重要な位置に配置されたnginxだと設定を書き換える際に、既存の構成を壊さないか、あるいは意図した通りに動作するのか事前に調べておきたいということがあります。

本物のnginxを立ててログを調べてもよいですが、手元で再現できて、テストができると便利じゃないかということで、dockerでnginxのやや複雑な設定をテストする環境を作りました。

github.com

続きを読む

MySQLで定期的に SHOW PROCESSLIST を実行して長時間走っているクエリを探す

前略、大きいMySQLのデータベースがあります。すると、大きなデータベースから多くのデータを取得するため、非常に重いクエリが実行されることがあります。 そうするとデータベースが高負荷になるため重い処理を見つけたくなります。 (innodb_query_queued とかが増えて辛くなる)

MySQLには SHOW PROCESSLIST というものがあり、実行中のMySQLのプロセス一覧を見ることができ、 クエリの実行状況や実行時間をみることができるのでスロークエリログより便利なことがあります。 (スロークエリログはクエリが完了した場合に出力されるため実行中やクエリを中断した場合に見ることができない)

しかし、SHOW PROCESSLIST の出力は多いため毎回見るのは疲れます。そこで以下のようなスクリプトSHOW FULL PROCESSLIST の出力をフィルターすると便利です。

require 'mysql2'

MYSQL_USER = ''
MYSQL_PASS = ''
LONG_QUERY_THRESHOLD = 60

client = Mysql2::Client.new(host: 'localhost', username: MYSQL_USER, password: MYSQL_PASS)
client.query('SHOW FULL PROCESSLIST').each do |row|
  next unless row["Command"] == "Query"
  next if row["Time"] < LONG_QUERY_THRESHOLD

  puts ([Time.now] + row.values.map { |v| v.to_s&.gsub("\n", " ") }).join("\t")
end

実行コマンドがQueryかつ実行時間の閾値を超えた場合にのみ出力します。 複数回の出力をフィルターしないので、時間がかかっているクエリはなんども見ることになります。クエリに長い文字列が来ることもあるので、 実運用のことを考えるとある程度の長さで切った方がいいかもですね。