GitHub の Pages を maven リポジトリとして使用するときのアカウント情報をセキュアにする(OAuth2Token)

自分自身が半年振りに GitHub の Pages を
maven リポジトリとして使用しようとして検索したところ
大体のページが ~/.m2/settings.xml に GitHub のアカウント情報を
暗号化無しで記載する手順になっていました。
(パーミッション 700 に設定する説明がありますが Windows では設定が一筋縄ではいかない…)

知っていて当たり前として省略しているのか
セキュリティ面が弱いので補足です。

さらに raw など既に使用できないものを使用していたり
github.io に追従していなかったりするので今現在での手順となります。

最初に英語で参考にしたのが

http://stackoverflow.com/questions/14013644/hosting-a-maven-repository-on-github

となりますがいろいろと古くなっています。

基本的に GitHub へのアップは release のみで

  • snapshot の deploy は行わない
  • mvn deploy ではアップしない
  • maven-release-plugin を使用してリリースを行うときのみアップロード

するようにします。

GitHub のリポジトリの設定で Pages を作成してください。
Pages を有効にすると gh-pages というブランチが作成されます。

今回は
gh-pages ブランチの maven フォルダにたいして mvn site の結果をアップ
gh-pages ブランチの maven/relases フォルダにたいしてリリース版の maven リポジトリをアップ
するようにしてみます。

アカウント設定ですが

  <servers>
    <server>
      <id>mygithub</id>
      <username>ユーザー名</username>
      <password>パスワード</password>
    </server>
  </servers>

で平文で保存するのではなく

http://maven.apache.org/guides/mini/guide-encryption.html

を参考にして暗号化されたパスワードを格納するようにしてください。
(こちらの暗号化処理ですがコードを追っかけてみましたがすぐに戻せる状態ではあるので気休めにしかなりません。)

暗号化したパスワードは手順が面倒ですので
OAuth2 のトークンで行うほうがトークンの破棄を行えるため便利だとおもいます。

OAuth2 のトークンは GitHub のアカウント設定から「Applications」を選択して
「Personal Access Tokens」で「Create new token」をクリックしてください。
16進数の文字列が現れるのでそちらをメモして置いてください。
(「Edit」でトークンが表示されないように変更しておくほうがいいと思います。)

先ほどメモした OAuth2 のトークンを

  <servers>
    <server>
      <id>mygithub</id>
      <password>OAuth2 トークン</password>
    </server>
  </servers>

と usename を削除してパスワードに OAuth2 トークンを設定することで
GitHub へのアップロード時には OAuth2 トークンが使用されるようになります。
(パーミッションを 600 などに変更しやすい環境では 600 に変更したほうがセキュアになります。)

OAuth2トークンですので万が一流出した場合でも
GitHub のアカウント設定から削除(delete)できます。

そのため GitHub アカウントのパスワードよりも流出した場合の影響を軽減できるかとおもいます。
(APIを叩いてメールアドレス等が取得できる場合は影響範囲が同じになってしまいますが…)

試していませんがパスワード部分ですので

http://maven.apache.org/guides/mini/guide-encryption.html

でマスターパスワードによる暗号化を行えるかもしれません。

site プラグインによるアップロードを禁止するために
プロパティに以下の設定を追加

  <properties>

    <dryRun>true</dryRun>
    <github.site.skip>true</github.site.skip> <!-- over 0.9 -->

  </properties>

ビルドに対するプラグインに設定を追加

  <build>
    <plugins>

      
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-site-plugin</artifactId>
        <version>3.3</version>
        <inherited>true</inherited>
        <configuration>
          <skipDeploy>true</skipDeploy> <!-- mvn site:deploy で site をアップしないように設定 -->
        </configuration>
      </plugin>
      
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-deploy-plugin</artifactId>
        <version>2.8.1</version>
        <configuration>
          <altReleaseDeploymentRepository>internal.repo::default::file:///${project.reporting.outputDirectory}/releases</altReleaseDeploymentRepository>
          <altSnapshotDeploymentRepository>internal.repo::default::file:///${project.reporting.outputDirectory}/snapshots</altSnapshotDeploymentRepository>
        </configuration>
      </plugin>

    </plugins>
  </build>

この状態になった段階で mvn deploy で
target/site/snapshot にスナップショットの maven リポジトリが作成されるのを確認してください。

実際に github へアップするためのプラグインを追加


      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-release-plugin</artifactId>
        <version>2.4.2</version>
        <configuration>
          <dryRun>${dryRun}</dryRun>
          <goals>deploy</goals>
        </configuration>
        <dependencies>
          <dependency>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-scm-plugin</artifactId>
            <version>1.8.1</version>
          </dependency>
        </dependencies>
      </plugin>

      <plugin>
        <groupId>com.github.github</groupId>
        <artifactId>site-maven-plugin</artifactId>
        <version>0.9</version>
        <inherited>true</inherited>
        <configuration>
          <message>Maven artifacts for ${project.artifactId} ${project.version}</message>
          <noJekyll>true</noJekyll>
          <outputDirectory>${project.reporting.outputDirectory}</outputDirectory>
          <excludes>
            <exclude>snapshots</exclude>
          </excludes>
          <branch>refs/heads/gh-pages</branch>
          <merge>true</merge>
          <path>maven</path>
          <dryRun>${dryRun}</dryRun>
        </configuration>
        <executions>
          <execution>
            <phase>deploy</phase>
            <goals>
              <goal>site</goal>
            </goals>
          </execution>
        </executions>
      </plugin>

リリースプラグインを使用してリリースを行うことで
リリース処理中に gh-pages ブランチに対して

  • site が gh-pages/maven
  • site/releases が gh-pages/maven/releases へリリースリポジトリ

といったようにアップさせるようになります。
(リリースプラグインの設定が必要です。)

今まで行ってきた設定はセーフティにしてありますのでプロパティ設定を追加しないとリリースができなくなっています。
git へパスを通した上で

mvn -DdryRun=false -Dgithub.site.skip=false -Dgithub.global.server=mygithub

という感じでセーフティをはずさないと実際に GitHub へアップロード処理が行われないようにしてあります。
(github.global.server は ~/.m2/settings.xml へ OAuth2 を設定した id を指定してください。)

目論見では問題ないと思ったのですが、mvn release:perform で問題が発生しました!!

maven 3.0.5, com.github.github:site-maven-plugin 0.9 では
mvn release:perform でコマンドラインから与えたプロパティを読み取らなかったです。

そのため
mvn release:perform 完了後に

cd target
cd checkout
mvn -DdryRun=false -Dgithub.site.skip=false -Dgithub.global.server=mygithub deploy

としてデプロイ作業が必要です。

長くなりましたが最終的には以下のような pom.xml になります。

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <prerequisites>
    <maven>3.0.5</maven>
  </prerequisites>

  <groupId>jp.ne.sakura.kkkon</groupId>
  <artifactId>strip-elf-section-header</artifactId>
  <version>1.2-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>strip-elf-section-header</name>
  <description>Strip SectionHeader from ELF-file.</description>
  <url>https://github.com/kkkon/strip-elf-section-header</url>
  <inceptionYear>2013</inceptionYear>

  <issueManagement>
    <url>https://github.com/kkkon/strip-elf-section-header/issues</url>
    <system>GitHub Issues</system>
  </issueManagement>

  <licenses>
    <license>
      <name>The MIT license</name>
      <url>http://www.opensource.org/licenses/mit-license.php</url>
      <distribution>repo</distribution>
    </license>
  </licenses>

  <scm>
    <connection>scm:git:https://github.com/kkkon/strip-elf-section-header.git</connection>
    <developerConnection>scm:git:ssh://git@github.com/kkkon/strip-elf-section-header.git</developerConnection>
    <url>https://github.com/kkkon/strip-elf-section-header</url>
    <tag>HEAD</tag>
  </scm>

  <properties>
    <maven.compiler.encoding>UTF-8</maven.compiler.encoding>
    <maven.compiler.target>1.6</maven.compiler.target>
    <maven.compiler.source>1.6</maven.compiler.source>
    <maven.findbugs.enable>true</maven.findbugs.enable>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.build.outputEncoding>UTF-8</project.build.outputEncoding>
    <maven.test.skip>false</maven.test.skip>


    <dryRun>true</dryRun>
    <github.site.skip>true</github.site.skip> <!-- over 0.9 -->

  </properties>

  <dependencies>
    <dependency>
      <groupId>commons-cli</groupId>
      <artifactId>commons-cli</artifactId>
      <version>1.2</version>
      <scope>compile</scope>
    </dependency>

    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

  <build>
    <resources>
      <resource>
        <directory>${basedir}</directory>
        <includes>
          <include>LICENSE.txt</include>
        </includes>
        <targetPath>META-INF/kkkon</targetPath>
      </resource>
    </resources>

    <testResources>
      <testResource>
        <directory>testsrc/android</directory>
        <filtering>false</filtering>
        <includes>
          <include>**/*.so</include>
        </includes>
        <targetPath>${project.build.testOutputDirectory}/elf/android</targetPath>
      </testResource>
    </testResources>
 
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-source-plugin</artifactId>
        <version>2.2.1</version>
        <executions>
          <execution>
            <phase>package</phase>
            <goals>
              <goal>jar</goal>
            </goals>
          </execution>
        </executions>
      </plugin>

      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-jar-plugin</artifactId>
        <version>2.4</version>
        <configuration>
          <archive>
            <index>true</index>
            <manifest>
              <mainClass>jp.ne.sakura.kkkon.StripElfSectionHeader.App</mainClass>
              <!--
              <addClasspath>true</addClasspath>
              <classpathPrefix>lib/</classpathPrefix>
              -->
            </manifest>
          </archive>
        </configuration>
      </plugin>
      
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-shade-plugin</artifactId>
        <version>2.1</version>
        <executions>
          <execution>
            <phase>package</phase>
            <goals>
              <goal>shade</goal>
            </goals>
            <configuration>
              <createSourcesJar>false</createSourcesJar>
              <shadedArtifactAttached>true</shadedArtifactAttached>
              <shadedClassifierName>shaded</shadedClassifierName>
            </configuration>
          </execution>
        </executions>
      </plugin>




      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-deploy-plugin</artifactId>
        <version>2.8.1</version>
        <configuration>
          <altReleaseDeploymentRepository>internal.repo::default::file:///${project.reporting.outputDirectory}/releases</altReleaseDeploymentRepository>
          <altSnapshotDeploymentRepository>internal.repo::default::file:///${project.reporting.outputDirectory}/snapshots</altSnapshotDeploymentRepository>
        </configuration>
      </plugin>


      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-site-plugin</artifactId>
        <version>3.3</version>
        <inherited>true</inherited>
        <configuration>
          <skipDeploy>true</skipDeploy>
        </configuration>
      </plugin>

      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-release-plugin</artifactId>
        <version>2.4.2</version>
        <configuration>
          <dryRun>${dryRun}</dryRun>
          <goals>deploy</goals>
        </configuration>
        <dependencies>
          <dependency>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-scm-plugin</artifactId>
            <version>1.8.1</version>
          </dependency>
        </dependencies>
      </plugin>

      <plugin>
        <groupId>com.github.github</groupId>
        <artifactId>site-maven-plugin</artifactId>
        <version>0.9</version>
        <inherited>true</inherited>
        <configuration>
          <message>Maven artifacts for ${project.artifactId} ${project.version}</message>
          <noJekyll>true</noJekyll>
          <outputDirectory>${project.reporting.outputDirectory}</outputDirectory>
          <excludes>
            <exclude>snapshots</exclude>
          </excludes>
          <branch>refs/heads/gh-pages</branch>
          <merge>true</merge>
          <path>maven</path>
          <dryRun>${dryRun}</dryRun>
        </configuration>
        <executions>
          <execution>
            <phase>deploy</phase>
            <goals>
              <goal>site</goal>
            </goals>
          </execution>
        </executions>
      </plugin>

    </plugins>
  </build>
  
  <reporting>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-report-plugin</artifactId>
        <version>2.16</version>
        <reportSets>
          <reportSet>
            <reports>
              <report>report-only</report>
            </reports>
          </reportSet>
        </reportSets>
      </plugin>
      
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-project-info-reports-plugin</artifactId>
        <version>2.7</version>
        <reportSets>
          <reportSet>
            <reports>
              <report>index</report>
              <report>dependencies</report>
              <report>dependency-info</report>
              <report>issue-tracking</report>
              <report>license</report>
              <report>scm</report>
              <report>summary</report>
            </reports>
          </reportSet>
        </reportSets>
      </plugin>
      
    </plugins>
  </reporting>

  <distributionManagement>
    <repository>
      <id>release-kkkon.github.io</id>
      <name>Strip SectionHeader from ELF-file Maven Release Repository</name>
      <url>http://kkkon.github.io/strip-elf-section-header/maven/releases</url>
    </repository>
    <snapshotRepository>
      <id>snapshot-kkkon.github.io</id>
      <name>Strip SectionHeader from ELF-file Maven Snapshot Repository</name>
      <url>http://kkkon.github.io/strip-elf-section-header/maven/snapshots</url>
    </snapshotRepository>
    <site>
      <id>kkkon.github.io</id>
      <name>Strip SectionHeader from ELF-file Maven Site</name>
      <url>http://kkkon.github.io/strip-elf-section-header</url>
    </site>
  </distributionManagement>

</project>

This entry was posted in GitHub, Java, maven. Bookmark the permalink.

2 Responses to GitHub の Pages を maven リポジトリとして使用するときのアカウント情報をセキュアにする(OAuth2Token)

  1. diverKon says:

    com.github.github:site-maven-plugin ですが
    マスターパスワードによる暗号化をサポートしていませんでした。

    さすがに困るので Pull Request を投げました。
    https://github.com/github/maven-plugins/pull/59

  2. diverKon says:

    おおう、マージされました。
    0.10 がリリースされたら暗号化がサポートされるようになります。

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>