Ubuntu 14.04隐藏Apache-2.4的版本号与操作系统类型

一般情况下,软件的漏洞信息和特定版本,特定操作系统是相关的,因此,软件的版本号以及操作系统类型对攻击者来说是很有价值的。

在默认情况下,Apache会在返回信息中把自身的版本号,操作系统类型都显示出来,如下图:
Apache2-403

这样做会造成潜在的安全风险,导致不必要的攻击行为。

Ubuntu 14.04系统上隐藏Apache-2.4的版本号与操作系统类型的方法如下:

$ sudo vim /etc/apache2/conf-enabled/security.conf

把文件中的的ServerTokens OS修改为ServerTokens Prod,ServerSignature On修改为ServerSignature Off,如下图所示:

apache2-security-conf

修改完成后,重启Apache2的服务

$ sudo service apache2 restart

修改后的结果如下图所示,已经没有系统类型信息了,仅仅返回了一个403错误。

Apache2-404-Modify

阿里云服务器从Ubuntu 12.04升级到Ubuntu 14.04

阿里云的服务器是Ubuntu 12.04根据Canonical发布的支持路线图,可以看到2017年4月份之后就不再提供支持。因此很有升级导致Ubuntu 14.04的必要,更别说很多软件在Ubuntu 12.04上已经比较过时了。

Ubuntu LTS版本支持路线图如下图:
1_201204291858511OI60

升级的流程如下所示:(执行下面操作之前,请务必先备份重要数据,阿里云服务器推荐使用自带的系统快照功能,非常好用)

1.首先保证当前系统上的软件都是最新的


$sudo apt-get update
$sudo apt-get dist-upgrade

2.安装系统升级模块


$sudo apt-get install update-manager-core
$sudo do-release-upgrade -d

1-do-release-upgrade

3.升级流程


允许系统在升级期间开放1022端口用来处理系统升级异常,当系统升级异常的时候,可以通过这个端口进行某些恢复操作。(实际上没太大作用,出问题就快照回滚了,更快速安全方便)
2-ssh-port-query-yes

输入y,点击回车(Enter)。

3-iptables-add-port-press-enter

点击回车(Enter),允许在iptable上面开放1022端口出来,这个端口在安装完成后会自动关闭,不需要过多关心。

4-rewrite-sources-list-yes

允许升级程序更新sources.list用来获取升级所需要的文件,输入y,点击回车(Enter)。

5-upgrade-confirm

询问是否确认系统升级,输入y,点击回车(Enter)。

6-disable-ssh-password-no

询问是否禁止root用户通过ssh访问系统,这个一定要选择No,否则升级完成后,我们无法远程登陆系统。

7-restart-services-without-asking-yes

询问在升级期间是否允许自动重启需要升级的服务,这个一定要选择Yes,否则会不断的询问你是不是确定重启服务,非常麻烦。

8-serurity-limits-conf-replace-enter

询问是否用新系统的文件替换原系统的/etc/security/limits.conf文件,直接回车(Enter),不允许替换,使用原系统的配置。

9-etc-default-rcS-enter

同上,直接回车(Enter)。

9-etc-default-rcS-enter

同上,直接回车(Enter)。

10-etc-sysctl-conf-enter

同上,直接回车(Enter)。

11-etc-vsftpd-conf-enter

同上,直接回车(Enter)。

12-etc-php5-fpm-php-fpm-conf-enter

同上,直接回车(Enter)。

13-etc-php5-fpm-php-ini-enter

询问是否替换文件,同上,直接回车(Enter),不允许替换。

14-etc-php5-cgi-php-ini-enter

同上,直接回车(Enter)。

15-etc-init-mounted-run-conf-enter

同上,直接回车(Enter)。

16-etc-apache2-mods-available-fcgid-conf-enter

同上,直接回车(Enter)。

17-etc-sv-git-daemon-run-enter

同上,直接回车(Enter)。

18-etc-default-tomcat7-enter

同上,直接回车(Enter)。

19-upgrade-phpmyadmin-enter

询问是否升级数据库,此处选择Yes,回车(Enter)。

20-upgrade-phpmyadmin-password-enter

输入数据库的密码,完成后点击回车(Enter)。

21-remove-obsolete-packages-yes

询问是否删除不再使用的安装包,输入y后点击回车(Enter)。

22-restart-required-yes

升级完成,询问是否重启系统,输入y后点击回车(Enter)。系统会重启,远程连接会断开,需要稍等几分钟后重新连接服务器。

3.恢复被修改后的系统配置信息


安装Apache2PHP扩展libapache2-mod-php5,Ubuntu 12.04版本的库,在升级的过程中被丢弃了,需要重新手动安装。

23-after-restart-install-libapache2-mod-php5

询问是否替换已经存在的PHP配置文件,直接点击回车,不允许替换。

24-after-restart-install-libapache2-mod-php5-php-ini-enter

修改Apache2的配置文件

$sudo vim /etc/apache2/apache2.conf

25-after-restart-vim-apache2-conf

原有Apache 2.2配置为:

Include sites-enabled/

发现升级后变更为:

IncludeOptional sites-enabled/*.conf

导致PHP无法正常工作,因此需要修改回来。

修改前:
26-after-restart-vim-apache2-conf-IncludeOptional

修改后:27-after-restart-vim-apache2-conf-IncludeOptional-modify-complete

Apache 2.4修改了默认目录位置(这导致2.2版本设置的禁止目录流量功能失效),并且默认开启了目录浏览功能,会导致潜在的安全问题,需要手工关闭.

修改前:29-after-restart-apache2-disable-indexs

修改后:30-after-restart-apache2-disable-indexs-modify

重启Apache2

$sudo service apache2 restart

28-after-restart-apache2-restart

到此,整个系统升级完成,所有功能恢复正常。

从升级的效果来看,服务器的响应明显变快,非常值得升级!

Shared Preferences的分析

The SharedPreferences class provides a general framework that allows you to save and retrieve persistent key-value pairs of primitive data types. You can use SharedPreferences to save any primitive data: booleans, floats, ints, longs, and strings. This data will persist across user sessions (even if your application is killed).

调用getSharedPreferences()获取对应的的文件,该函数实现功能如下:

//Context类静态数据集合,以键值对保存了所有读取该xml文件后所形成的数据集合

private static final HashMap<File, SharedPreferencesImpl> sSharedPrefs =new HashMap<File, SharedPreferencesImpl>();

可以看到他有一个Map, 而针对SharedPreferencesImpl里面,由会有map, 这样也就可以证明, 为什么SharedPreference被广泛使用了。 他在普通时刻,内容是从内存里面直接读取的, 只有在第一次启动时,是IO操作。

2. apply()commit()的区别

/** boolean commit();的注释如下:

* Commit your preferences changes back from this Editor to the
* {@link SharedPreferences} object it is editing. This atomically
* performs the requested modifications, replacing whatever is currently
* in the SharedPreferences.
*
*

Note that when two editors are modifying preferences at the same
* time, the last one to call commit wins.
*
*

If you don't care about the return value and you're
* using this from your application's main thread, consider
* using {@link #apply} instead. 如果你不考虑返回值,你在主线程中已经使用commit,那么你可以考虑替换使用apply
*
* @return Returns true if the new values were successfully written
* to persistent storage.
*/

apply方法的注释:

*Unlike {@link #commit}, which writes its preferences out
* to persistent storage synchronously, {@link #apply}
* commits its changes to the in-memory
* {@link SharedPreferences} immediately but starts an
* asynchronous commit to disk and you won't be notified of
* any failures. If another editor on this
* {@link SharedPreferences} does a regular {@link #commit}
* while a {@link #apply} is still outstanding, the
* {@link #commit} will block until all async commits are
* completed as well as the commit itself.

apply不同于commitcommit是同步的去更改硬盘上的东西,而apply是先直接更改内存中的, 然后异步的去更改应硬盘中的内容。

不用去担心线程安全问题, 因为如果一个其他的线程去commit,而刚好有一个还没有完成的applycommit会被阻塞到异步线程提交完成。

*
*

As {@link SharedPreferences} instances are singletons within
* a process, it's safe to replace any instance of {@link #commit} with
* {@link #apply} if you were already ignoring the return value. 如果你真的可以忽略返回值,恰好SharedPreferences又是单例模式的,那就可以安全的用apply来替换commit
*
*

You don't need to worry about Android component
* lifecycles and their interaction with apply()
* writing to disk. The framework makes sure in-flight disk
* writes from apply() complete before switching
* states. 也不需要去关心android组件的声明周期。 框架会保证完成所有apply之后,才切换状态。

参考链接


Shared Preferences的分析

Android Studio中的productFlavors指定默认编译执行的任务

Android Studio中指定了productFlavors如下:

    productFlavors {
        /*日常*/
        Daily {
        }
        /*线上*/
        Online {
        }
        /*预发*/
        Advance {
        }
    }

整个的build.gradle里面的内容如下:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.2"

    defaultConfig {
        applicationId "com.my.myapplication"
        minSdkVersion 15
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

    productFlavors {
        /*日常*/
        Daily {
        }
        /*线上*/
        Online {
        }
        /*预发*/
        Advance {
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.2.1'
}

但是这个时候我们点击Android Studio的调试按钮的时候,不知道究竟是使用哪个Flavors来编译,比如在Android Studio 1.5的时候,是按照从上到下的顺序处理的,默认是使用排在第一个的Daily,而到了Android Studio 2.1 Preview 5版本,却变成了按照字母排序,结果变成了默认编译Advance

网上搜索了一下,找到如下解决方法:

选择"Build Variant",然后在出现的窗口中选择其中一个选项作为默认的编译,运行选项即可。

BuildVariantSel

参考链接


Gradle Build only a flavour

Android Studio(Gradle)解决库依赖冲突问题

最近在调整代码的时候,出现如下问题:

Cause: com.android.dex.DexException: Multiple dex files define Landroid/support/annotation/AnimRes;
    UNEXPECTED TOP-LEVEL EXCEPTION:
com.android.dex.DexException: Multiple dex files define Landroid/support/annotation/AnimRes;
        at com.android.dx.merge.DexMerger.readSortableTypes(DexMerger.java:579)
        at com.android.dx.merge.DexMerger.getSortedTypes(DexMerger.java:535)
        at com.android.dx.merge.DexMerger.mergeClassDefs(DexMerger.java:517)
        at com.android.dx.merge.DexMerger.mergeDexes(DexMerger.java:164)
        at com.android.dx.merge.DexMerger.merge(DexMerger.java:188)
        at com.android.dx.command.dexer.Main.mergeLibraryDexBuffers(Main.java:504)
        at com.android.dx.command.dexer.Main.runMonoDex(Main.java:334)
        at com.android.dx.command.dexer.Main.run(Main.java:277)
        at com.android.dx.command.dexer.Main.main(Main.java:245)
        at com.android.dx.command.Main.main(Main.java:106)

网上查询了一下,找到如下的解决方法:

我们常常用gradle.build文件导入依赖库,但是有时候库依赖会发生版本冲突或多个模块依赖同一个库的情况。

这就引出两个问题,如下:

  • 版本冲突时,Gradle会下载多个版本的依赖库吗?
  • 当多个模块依赖同一个库时,每个模块都会去下载该依赖库吗?
    为解决这疑问,接下来我们在Android StudioGradle举个例子:
    gradle.build依赖部分的配置:
dependencies {
    compile 'com.android.support:appcompat-v7:22.2.1'
    compile ('com.android.support:design:22.2.1')
    compile 'com.shamanland:fonticon:0.1.8'
    androidTestCompile 'com.android.support:support-annotations:22.2.1'
    androidTestCompile 'com.android.support.test:runner:0.3'
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2')
}

在文件目录下或Android StudioTerminal下敲gradlew -q app:dependencies 命令,便有以下输出:

_debugAndroidTestApk - ## Internal use, do not manually configure ##
+--- com.android.support:support-annotations:22.2.1
+--- com.android.support.test:runner:0.3
|    +--- com.android.support.test:exposed-instrumentation-api-publish:0.3
|    +--- junit:junit:4.12
|    |    \--- org.hamcrest:hamcrest-core:1.3
|    \--- com.android.support:support-annotations:22.2.0 -> 22.2.1
\--- com.android.support.test.espresso:espresso-core:2.2
     +--- com.android.support.test.espresso:espresso-idling-resource:2.2
     +--- com.squareup:javawriter:2.1.1
     +--- javax.inject:javax.inject:1
     +--- org.hamcrest:hamcrest-library:1.3
     |    \--- org.hamcrest:hamcrest-core:1.3
     +--- com.android.support.test:rules:0.3
     |    \--- com.android.support.test:runner:0.3 (*)
     +--- org.hamcrest:hamcrest-integration:1.3
     |    \--- org.hamcrest:hamcrest-library:1.3 (*)
     +--- com.google.code.findbugs:jsr305:2.0.1
     +--- javax.annotation:javax.annotation-api:1.2
     \--- com.android.support.test:runner:0.3 (*)

_debugAndroidTestCompile - ## Internal use, do not manually configure ##
+--- com.android.support:support-annotations:22.2.1
+--- com.android.support.test:runner:0.3
|    +--- com.android.support.test:exposed-instrumentation-api-publish:0.3
|    +--- junit:junit:4.12
|    |    \--- org.hamcrest:hamcrest-core:1.3
|    \--- com.android.support:support-annotations:22.2.0 -> 22.2.1
\--- com.android.support.test.espresso:espresso-core:2.2
     +--- com.android.support.test.espresso:espresso-idling-resource:2.2
     +--- com.squareup:javawriter:2.1.1
     +--- javax.inject:javax.inject:1
     +--- org.hamcrest:hamcrest-library:1.3
     |    \--- org.hamcrest:hamcrest-core:1.3
     +--- com.android.support.test:rules:0.3
     |    \--- com.android.support.test:runner:0.3 (*)
     +--- org.hamcrest:hamcrest-integration:1.3
     |    \--- org.hamcrest:hamcrest-library:1.3 (*)
     +--- com.google.code.findbugs:jsr305:2.0.1
     +--- javax.annotation:javax.annotation-api:1.2
     \--- com.android.support.test:runner:0.3 (*)

_debugApk - ## Internal use, do not manually configure ##
+--- com.android.support:multidex:1.0.1
+--- com.android.support:appcompat-v7:22.2.1
|    \--- com.android.support:support-v4:22.2.1
|         \--- com.android.support:support-annotations:22.2.1
+--- com.android.support:design:22.2.1
|    +--- com.android.support:appcompat-v7:22.2.1 (*)
|    \--- com.android.support:support-v4:22.2.1 (*)
\--- com.shamanland:fonticon:0.1.8

_debugCompile - ## Internal use, do not manually configure ##
+--- com.android.support:multidex:1.0.1
+--- com.android.support:appcompat-v7:22.2.1
|    \--- com.android.support:support-v4:22.2.1
|         \--- com.android.support:support-annotations:22.2.1
+--- com.android.support:design:22.2.1
|    +--- com.android.support:appcompat-v7:22.2.1 (*)
|    \--- com.android.support:support-v4:22.2.1 (*)
\--- com.shamanland:fonticon:0.1.8

_debugUnitTestApk - ## Internal use, do not manually configure ##
No dependencies

_debugUnitTestCompile - ## Internal use, do not manually configure ##
No dependencies

_releaseApk - ## Internal use, do not manually configure ##
+--- com.android.support:multidex:1.0.1
+--- com.android.support:appcompat-v7:22.2.1
|    \--- com.android.support:support-v4:22.2.1
|         \--- com.android.support:support-annotations:22.2.1
+--- com.android.support:design:22.2.1
|    +--- com.android.support:appcompat-v7:22.2.1 (*)
|    \--- com.android.support:support-v4:22.2.1 (*)
\--- com.shamanland:fonticon:0.1.8

_releaseCompile - ## Internal use, do not manually configure ##
+--- com.android.support:multidex:1.0.1
+--- com.android.support:appcompat-v7:22.2.1
|    \--- com.android.support:support-v4:22.2.1
|         \--- com.android.support:support-annotations:22.2.1
+--- com.android.support:design:22.2.1
|    +--- com.android.support:appcompat-v7:22.2.1 (*)
|    \--- com.android.support:support-v4:22.2.1 (*)
\--- com.shamanland:fonticon:0.1.8

_releaseUnitTestApk - ## Internal use, do not manually configure ##
No dependencies

_releaseUnitTestCompile - ## Internal use, do not manually configure ##
No dependencies

androidJacocoAgent - The Jacoco agent to use to get coverage data.
\--- org.jacoco:org.jacoco.agent:0.7.4.201502262128

androidJacocoAnt - The Jacoco ant tasks to use to get execute Gradle tasks.
\--- org.jacoco:org.jacoco.ant:0.7.4.201502262128
     +--- org.jacoco:org.jacoco.core:0.7.4.201502262128
     |    \--- org.ow2.asm:asm-debug-all:5.0.1
     +--- org.jacoco:org.jacoco.report:0.7.4.201502262128
     |    +--- org.jacoco:org.jacoco.core:0.7.4.201502262128 (*)
     |    \--- org.ow2.asm:asm-debug-all:5.0.1
     \--- org.jacoco:org.jacoco.agent:0.7.4.201502262128

androidTestApk - Classpath packaged with the compiled 'androidTest' classes.
No dependencies

androidTestCompile - Classpath for compiling the androidTest sources.
+--- com.android.support:support-annotations:22.2.1
+--- com.android.support.test:runner:0.3
|    +--- com.android.support.test:exposed-instrumentation-api-publish:0.3
|    +--- junit:junit:4.12
|    |    \--- org.hamcrest:hamcrest-core:1.3
|    \--- com.android.support:support-annotations:22.2.0 -> 22.2.1
\--- com.android.support.test.espresso:espresso-core:2.2
     +--- com.android.support.test.espresso:espresso-idling-resource:2.2
     +--- com.squareup:javawriter:2.1.1
     +--- javax.inject:javax.inject:1
     +--- org.hamcrest:hamcrest-library:1.3
     |    \--- org.hamcrest:hamcrest-core:1.3
     +--- com.android.support.test:rules:0.3
     |    \--- com.android.support.test:runner:0.3 (*)
     +--- org.hamcrest:hamcrest-integration:1.3
     |    \--- org.hamcrest:hamcrest-library:1.3 (*)
     +--- com.google.code.findbugs:jsr305:2.0.1
     +--- javax.annotation:javax.annotation-api:1.2
     \--- com.android.support.test:runner:0.3 (*)

androidTestProvided - Classpath for only compiling the androidTest sources.
No dependencies

androidTestWearApp - Link to a wear app to embed for object 'androidTest'.
No dependencies

apk - Classpath packaged with the compiled 'main' classes.
No dependencies

archives - Configuration for archive artifacts.
No dependencies

compile - Classpath for compiling the main sources.
+--- com.android.support:appcompat-v7:22.2.1
|    \--- com.android.support:support-v4:22.2.1
|         \--- com.android.support:support-annotations:22.2.1
+--- com.android.support:design:22.2.1
|    +--- com.android.support:appcompat-v7:22.2.1 (*)
|    \--- com.android.support:support-v4:22.2.1 (*)
\--- com.shamanland:fonticon:0.1.8

可以看出:com.android.support.test:runner:0.3 这个模块原本是依赖于com.android.support:support-annotations22.2.0版本,但由于你又在gradle.build中加了这行androidTestCompile 'com.android.support:support-annotations:22.2.1'gradle就会下载com.android.support:support-annotations22.2.1版本,而不会去下载com.android.support:support-annotations22.2.0版本,因此com.android.support.test:runner:0.3 就会被强转变依赖于com.android.support:support-annotations22.2.1版本
第二个问题,我还是利用上面gradle命令行打出的信息来看看:

debugApk - ## Internal use, do not manually configure ##
+--- com.android.support:multidex:1.0.1
+--- com.android.support:appcompat-v7:22.2.1
|    \--- com.android.support:support-v4:22.2.1
|         \--- com.android.support:support-annotations:22.2.1
+--- com.android.support:design:22.2.1
|    +--- com.android.support:appcompat-v7:22.2.1 (*)
|    \--- com.android.support:support-v4:22.2.1 (*)
\--- com.shamanland:fonticon:0.1.8

仔细看上面的依赖,com.android.support:appcompat-v7:22.2.1com.android.support:design:22.2.1,有共同依赖一个com.android.support:support-v4:22.2.1库,且com.android.support:design:22.2.1 依赖于com.android.support:appcompat-v7:22.2.1,但从打印出的信息可以看出com.android.support:design:22.2.1 依赖两个库的信息被打了星号标记,这标记意思是忽略这两个依赖的意思,也就是说不去下载这两个库。
从上面的两个例子来看,gradle对于需要多个版本的依赖库来说,一般只会下载你配置导入那个版本,如果没有手动导入,那就会下载所有模块依赖的最新版本那个库,面对多个模块依赖同一个库,每个模块不都会去下载该依赖库,而是下载一个该依赖库,共享给多个模块。
修改配置文件为:

dependencies {
    compile 'com.android.support:appcompat-v7:22.2.1'
    compile ('com.android.support:design:22.2.1')
            {
                exclude group: 'com.android.support'
            }
    compile 'com.shamanland:fonticon:0.1.8'
    androidTestCompile 'com.android.support:support-annotations:22.2.1'
    androidTestCompile 'com.android.support.test:runner:0.3'
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2')
            {
                exclude  group:'com.android.support.test'
            }
}

打印信息:

$ gradlew -q app:dependencies

------------------------------------------------------------
Project :app
------------------------------------------------------------

_debugAndroidTestApk - ## Internal use, do not manually configure ##
+--- com.android.support:support-annotations:22.2.1
+--- com.android.support.test:runner:0.3
|    +--- com.android.support.test:exposed-instrumentation-api-publish:0.3
|    +--- junit:junit:4.12
|    |    \--- org.hamcrest:hamcrest-core:1.3
|    \--- com.android.support:support-annotations:22.2.0 -> 22.2.1
\--- com.android.support.test.espresso:espresso-core:2.2
     +--- com.android.support.test.espresso:espresso-idling-resource:2.2
     +--- com.squareup:javawriter:2.1.1
     +--- javax.inject:javax.inject:1
     +--- org.hamcrest:hamcrest-library:1.3
     |    \--- org.hamcrest:hamcrest-core:1.3
     +--- org.hamcrest:hamcrest-integration:1.3
     |    \--- org.hamcrest:hamcrest-library:1.3 (*)
     +--- com.google.code.findbugs:jsr305:2.0.1
     \--- javax.annotation:javax.annotation-api:1.2

_debugAndroidTestCompile - ## Internal use, do not manually configure ##
+--- com.android.support:support-annotations:22.2.1
+--- com.android.support.test:runner:0.3
|    +--- com.android.support.test:exposed-instrumentation-api-publish:0.3
|    +--- junit:junit:4.12
|    |    \--- org.hamcrest:hamcrest-core:1.3
|    \--- com.android.support:support-annotations:22.2.0 -> 22.2.1
\--- com.android.support.test.espresso:espresso-core:2.2
     +--- com.android.support.test.espresso:espresso-idling-resource:2.2
     +--- com.squareup:javawriter:2.1.1
     +--- javax.inject:javax.inject:1
     +--- org.hamcrest:hamcrest-library:1.3
     |    \--- org.hamcrest:hamcrest-core:1.3
     +--- org.hamcrest:hamcrest-integration:1.3
     |    \--- org.hamcrest:hamcrest-library:1.3 (*)
     +--- com.google.code.findbugs:jsr305:2.0.1
     \--- javax.annotation:javax.annotation-api:1.2

_debugApk - ## Internal use, do not manually configure ##
+--- com.android.support:multidex:1.0.1
+--- com.android.support:appcompat-v7:22.2.1
|    \--- com.android.support:support-v4:22.2.1
|         \--- com.android.support:support-annotations:22.2.1
+--- com.android.support:design:22.2.1
\--- com.shamanland:fonticon:0.1.8

_debugCompile - ## Internal use, do not manually configure ##
+--- com.android.support:multidex:1.0.1
+--- com.android.support:appcompat-v7:22.2.1
|    \--- com.android.support:support-v4:22.2.1
|         \--- com.android.support:support-annotations:22.2.1
+--- com.android.support:design:22.2.1
\--- com.shamanland:fonticon:0.1.8

_debugUnitTestApk - ## Internal use, do not manually configure ##
No dependencies

_debugUnitTestCompile - ## Internal use, do not manually configure ##
No dependencies

_releaseApk - ## Internal use, do not manually configure ##
+--- com.android.support:multidex:1.0.1
+--- com.android.support:appcompat-v7:22.2.1
|    \--- com.android.support:support-v4:22.2.1
|         \--- com.android.support:support-annotations:22.2.1
+--- com.android.support:design:22.2.1
\--- com.shamanland:fonticon:0.1.8

_releaseCompile - ## Internal use, do not manually configure ##
+--- com.android.support:multidex:1.0.1
+--- com.android.support:appcompat-v7:22.2.1
|    \--- com.android.support:support-v4:22.2.1
|         \--- com.android.support:support-annotations:22.2.1
+--- com.android.support:design:22.2.1
\--- com.shamanland:fonticon:0.1.8

_releaseUnitTestApk - ## Internal use, do not manually configure ##
No dependencies

_releaseUnitTestCompile - ## Internal use, do not manually configure ##
No dependencies

androidJacocoAgent - The Jacoco agent to use to get coverage data.
\--- org.jacoco:org.jacoco.agent:0.7.4.201502262128

androidJacocoAnt - The Jacoco ant tasks to use to get execute Gradle tasks.
\--- org.jacoco:org.jacoco.ant:0.7.4.201502262128
     +--- org.jacoco:org.jacoco.core:0.7.4.201502262128
     |    \--- org.ow2.asm:asm-debug-all:5.0.1
     +--- org.jacoco:org.jacoco.report:0.7.4.201502262128
     |    +--- org.jacoco:org.jacoco.core:0.7.4.201502262128 (*)
     |    \--- org.ow2.asm:asm-debug-all:5.0.1
     \--- org.jacoco:org.jacoco.agent:0.7.4.201502262128

androidTestApk - Classpath packaged with the compiled 'androidTest' classes.
No dependencies

androidTestCompile - Classpath for compiling the androidTest sources.
+--- com.android.support:support-annotations:22.2.1
+--- com.android.support.test:runner:0.3
|    +--- com.android.support.test:exposed-instrumentation-api-publish:0.3
|    +--- junit:junit:4.12
|    |    \--- org.hamcrest:hamcrest-core:1.3
|    \--- com.android.support:support-annotations:22.2.0 -> 22.2.1
\--- com.android.support.test.espresso:espresso-core:2.2
     +--- com.android.support.test.espresso:espresso-idling-resource:2.2
     +--- com.squareup:javawriter:2.1.1
     +--- javax.inject:javax.inject:1
     +--- org.hamcrest:hamcrest-library:1.3
     |    \--- org.hamcrest:hamcrest-core:1.3
     +--- org.hamcrest:hamcrest-integration:1.3
     |    \--- org.hamcrest:hamcrest-library:1.3 (*)
     +--- com.google.code.findbugs:jsr305:2.0.1
     \--- javax.annotation:javax.annotation-api:1.2

androidTestProvided - Classpath for only compiling the androidTest sources.
No dependencies

androidTestWearApp - Link to a wear app to embed for object 'androidTest'.
No dependencies

apk - Classpath packaged with the compiled 'main' classes.
No dependencies

archives - Configuration for archive artifacts.
No dependencies

compile - Classpath for compiling the main sources.
+--- com.android.support:appcompat-v7:22.2.1
|    \--- com.android.support:support-v4:22.2.1
|         \--- com.android.support:support-annotations:22.2.1
+--- com.android.support:design:22.2.1
\--- com.shamanland:fonticon:0.1.8

比较上面两种配置compile信息部分,后面一种配置的 com.android.support:design:22.2.1 就没有输出两个打星号的依赖库信息了。
因此遇到这两种情况是,是gradle能自动帮我们解决掉了这两种情况,对于如何使用gralde命令行查看库依赖(depends)请看官方文档

参考链接


gradle 管理依赖库两个问题

WordPress 4.4:禁用/关闭XML-RPC

最近网站的访问量统计发现,大量的访问请求来自第三方的国家,远远超过国内的访问量,主要是来自185.130.5.165这个IP的访问量严重的异常,怀疑是遭到了密码尝试攻击,跟踪日志:

tail -f /var/log/apache2/access.log

发现如下记录大量重复出现:

185.130.5.165 - - [06/Apr/2016:10:51:44 +0800] "POST /xmlrpc.php HTTP/1.0" 200 584 "-" "Mozilla/4.0 (compatible: MSIE 7.0; Windows NT 6.0)"

由于我并不使用XML-RPC服务,因此考虑禁止对于xmlrpc.php的访问。

目前由于网站开启了.htacess的支持,因此,发现在.htacess中禁止文件访问是最高效的办法。

.htacess的文件尾部增加如下语句即可:

# 禁止 WordPress xmlrpc.php 请求
<Files xmlrpc.php>
order deny,allow
deny from all
</Files>

修改后的文件内容变更为:

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# 禁止 WordPress xmlrpc.php 请求
<Files xmlrpc.php>
order deny,allow
deny from all
</Files>
# END WordPress

然后重启Apache2即可。

$sudo service apache2 restart

然后就会发现访问http://www.mobibrw.com/xmlrpc.php的时候,直接返回了403禁止访问了。

参考链接:


wordpress:禁用/关闭XML-RPC
利用xmlrpc.php对WordPress进行暴力破解攻击

Intel GM45集成显卡非对称内存导致花屏

Intel弹性双通道内存技术(Intel Flex Memory Technology),使用不同容量,不同规格甚至不成对的内存组成双通道,让系统配置和内存升级更具弹性。可惜的是在Intel GM45系列芯片的电脑上,两个容量不同的内存组成双通道会导致花屏,如下图所示:

BlurredScreen

解决这种情况的办法,只能是安装两个内存容量相同内存组成对称双通道才能彻底解决花屏的问题。

WordPress 4.4.2版本在设置固定链接后出现分类翻页异常(404)

为了配合WP Super Cache,必须对页面进行固定链接的设置,最初的设置是固定设置成/p=%post_id%的样子,如下图:
WordpressPermalinkSettingWrong

刚刚开始没发现异常,最近才发现,当一个分类的分页数量大于3页的时候,会出现打不开的情况。

当点击Android分类的时候,会发现文章分了11页,当点击第二页的时候,发现,链接地址中的"/"被替换成了"%2F",导致网页打不开,直接返回404,如下图的情况:

ReplaceBy%2F

搜索半天,用Ubuntu12.04下WordPress安装WP Super Cache后链接包含”%2F”导致分类链接返回404的方法总算是解决,本以为没问题了,结果当点击完成第二页,继续点击第三页的时候,继续出现无法访问,观察链接后,发现错的更离谱了。如下图:

ClickTheThirdPage

直接提示"该页无法显示"

URLInCorrect

仔细观察链接会发现,链接地址莫名的被增加了一段%2Fpage%2F2,明显是第二页的地址残留,于是手工去掉这个多余的信息,发现是可以正常访问的。

RemovedIncorrectUrl

这就比较扯淡了,说明是页面生成的时候发生了异常。应该是不能正确的处理链接地址中携带%2F这种转义字符的情况。

网上搜索很长世间,也没有任何的有用信息,结果重新修改了一下固定链接,修改成/%year%/%post_id%,结果一切正常了,由此可见,WordPress应该是只测试了一部分情况,只能处理固定格式的固定链接,随便修改会导致内部代码混乱。WordpressPermalinkSettingCorrect

如此修改后,链接地址中也不会出现"/"被替换成"%2F"的情况了。

Ubuntu12.04下WordPress安装WP Super Cache后链接包含”%2F”导致分类链接返回404

WordPress安装WP Super Cache后需要开启"固定链接",但是开启之后,发现在点击分类链接的时候,一旦出现多页,点击分页的时候返回404错误。
开始认为是重写规则设置得不对, 后来才发现, 是"%2F"导致Apache直接返回404错误.

比如浏览查看某个标签下的文章列表的链接为

http://www.mobibrw.com/p=/android/page/2

被重写后的URL变为:

http://www.mobibrw.com/p=%2Fandroid/page/2

这样"/"被替换为"%2F",当这个请求到达Apache的时候,被Apache直接返回404错误。
Apache有一个配置项"AllowEncodedSlashes", 默认是"Off", 也就是不允许请求路径(上例是 %2Fandroid/page/2)中包含编码后的斜杠'/'(在某些平台是反斜杠'\'). 这个选项的的相应代码在mod_rewrite模块被执行之前:

// request.c
AP_DECLARE(int) ap_process_request_internal(request_rec *r){
	if (d->allow_encoded_slashes) {
		access_status = ap_unescape_url_keep2f(r->parsed_uri.path);
	} else {
		access_status = ap_unescape_url(r->parsed_uri.path);
	}
}

// util.c
AP_DECLARE(int) ap_unescape_url(char *url){
	if (IS_SLASH(*x) || *x == '\0')
		badpath = 1;
	...
	else if (badpath)
		return HTTP_NOT_FOUND;
}

默认不允许包含"%2F". 如果请求路径中包含了, 那么ap_unescape_url()函数认为是无效的路径, 直接返回HTTP_NOT_FOUND, 最终浏览器得到的是"404 - Not Found"出错页面.

Apache的配置文件中增加AllowEncodedSlashes On即可.如下:

$sudo vim /etc/apache2/sites-enabled/000-default
ServerName www.mobibrw.com

<VirtualHost *:80>
        ServerName www.mobibrw.com
        ServerAlias www.mobibrw.com
        DocumentRoot /var/www/wordpress
        #当URL中存在%2F转义后的字符‘/’的时候,会直接返回404,因此需要设置此项
        AllowEncodedSlashes On
        <Directory />
                Options FollowSymLinks
                AllowOverride All
        </Directory>
        <Directory /var/www/wordpress>
                #Options Indexes FollowSymLinks MultiViews
                Options FollowSymLinks MultiViews
                AllowOverride All
                FCGIWrapper /usr/bin/php5-cgi .php
                Options ExecCGI SymLinksIfOwnerMatch
                Order allow,deny
                allow from all
        </Directory>

        ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
        <Directory "/usr/lib/cgi-bin">
                AllowOverride None
                Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
                Order allow,deny
                Allow from all
        </Directory>

        ErrorLog ${APACHE_LOG_DIR}/error.log

        # Possible values include: debug, info, notice, warn, error, crit,
        # alert, emerg.
        LogLevel warn

        CustomLog ${APACHE_LOG_DIR}/access.log combined

    Alias /doc/ "/usr/share/doc/"
    <Directory "/usr/share/doc/">
        Options Indexes MultiViews FollowSymLinks
        AllowOverride None
        Order deny,allow
        Deny from all
        Allow from 127.0.0.0/255.0.0.0 ::1/128
    </Directory>

</VirtualHost>

参考链接


链接包含"%2F"导致mod_rewrite失效

Windows下搭建基于Jenkins+Git+Gradle的Android持续集成

下载Jenkins


官网下载,如果官网下载存在问题,也可以在本站下载Jenkins

下载Gradle


目前Android Studio支持的是Gradle 2.8版本,因此下载2.8版本的即可。Gradle 2.8,也可以本站下载

安装Tomcat


官方主页Apache Tomcat。Windows下面建议下载32-bit/64-bit Windows Service Installer版本。
DownloadTomcat9

安装Jenkins


将下载的jenkins.war包直接放到tomcat下的webapps目录,启动tomcat,在浏览器输入:http://127.0.0.1:8080/jenkins

安装Git plugin,Gradle plugin,Android Lint Plugin插件


点击Jenkins首页的"Manage Jenkins"链接,如下图:
ManageJenkins

进入设置,点击"Manage Plugins",添加Git plugin,Gradle plugin,Android Lint Plugin

ManagePlugins在打开的页面中,搜索并且安装插件

PluginManagerInstall

系统配置


返回首页,点击" Manage Plugins",然后进入页面中选择Configure System,配置JDK,Gradle,Git的选项。

JenkinsConfigure
设置JDK
SettingJava

SettingJavaManual

新建项目


首页点击"创建一个新任务",如下图:
NewJenkinsJobs
在接下来的页面中,输入工程的名字,并且选择"Freestyle project"

NewJobsCreateSelect
设置Git中源代码的路径,如果是使用SSH证书认证的登陆,则在Credentials中进行配置,如下图:

JenkinsJobAndroidConfigureGitNew

接下来配置触发构建的条件,目前我们设置为每天晚上3点,注意里面输入的是H 3 * * *,每个字符之间都有一个英文的空格。

JenkinsJobAndroidConfigureTrigger

接下来,配置Gralde的编译,在构建项目中选择"Invoke Gradle Script",如下图:
InvokeGradleScript
在选项的Tasks栏目中输入clean build --stacktrace --debug,如下图:

InvokeGradleScriptTasks
接下来,配置构建后操作,一般增加Publish Android Lint results,Archive the artifacts这两项即可,具体的配置参考下图:

InvokeGradleScriptTasksAfterBuild

构建项目


BuildNow

检验构建结果


构建完成以后检查一下,如果在:

当前用户目录\.jenkins\jobs\Android\workspace\app\build\outputs\apk\

下面成功生成了APK文件,则说明配置是成功的。

参考链接


基于Jenkins+git+gradle的android持续集成,jenkinsgradle