前段时间给YTKKeyValueStore提出多一个计算表里行数的方法
也被接纳并且合并了,但是在pod里使用
pod 'YTKKeyValueStore'

pod install 后发现并没有自己提出的代码
可能要对方发布新版本才能使用

那问题来了,如果自己发现某个项目有bug或者自己增加功能,怎么引用呢?

自己项目是
https://github.com/hqlulu/YTKKeyValueStore

那可以到
https://github.com/hqlulu/YTKKeyValueStore/releases

建立一个release,比如tag version为0.1.3
然后,在项目里可以引用某个版本,指定地址和版本,比如:

pod 'YTKKeyValueStore', :git => 'https://github.com/hqlulu/YTKKeyValueStore', :branch => '0.1.3'


在项目里测试成功哦~

另外一个简单的方式,引用某个提交的名称即可:
pod "XLForm", :git => 'https://github.com/hqlulu/XLForm', :commit => '80663f914b9e696d72040109f09e72fe23ad6f5a'

管理和使用方式:

如果支持pod的,参考这个安装pod,以及使用方式
http://code4app.com/article/cocoapods-install-usage


有用的类库:

1 下拉刷新和底部自动触发加载更多
https://github.com/samvermette/SVPullToRefresh

2 表单操作
https://github.com/xmartlabs/XLForm

3 图表
https://github.com/kevinzhow/PNChart

4 通用网络图片
https://github.com/ibireme/YYWebImage

5 通用网络请求处理
https://github.com/AFNetworking/AFNetworking

6 JSON模型转换(待评估)​
https://github.com/icanzilb/JSONModel

7 提示
https://github.com/jdg/MBProgressHUD

8 配置项和简单数据存储
https://github.com/gangverk/GVUserDefaults

9 列表里的网络图片
https://github.com/rs/SDWebImage

10 缓存处理参考
https://github.com/tumblr/TMCache


我们在公司局域网建立一个服务器搭建网站,如果需要回家使用,那就需要做一些操作才能实现。
公司局域网可能具有如下特点:
1 外网IP随拨号会变动
2 部分端口不开放

对于外网IP固定的网络,操作起来很方便。
路由器上,把80端口映射到局域网的服务器ip即可
如果80端口不开放,那就映射一个自定义的端口即可,比如1080端口
然后把域名指向该IP即可

对于拨号变动IP的网络,这个问题就归结到如何知道现在的外网IP的问题了。
1 用花生壳之类的检测ip变化,可以绑定到你的域名
2 有外网服务器的话,可以定期报告给外网服务器,把域名指向外网服务器就可以轻松代理访问

下面举例说明:
局域网服务器A,公网服务器B

我们在B服务器做个接收的小脚本:
<?php        $ip = $_SERVER['REMOTE_ADDR'];
        $str = "server $ip:1080;#backend";
        $file = '/tmp/backend.log';
        file_put_contents($file, $str);
?>

这个PHP做成是可访问的地址即可,每次访问,就记录ip到文件里

nginx配置可以做一个backend,我们用脚本检查ip不同就可以重载nginx:

upstream welinkers{
server 1.2.254.97:1080;#backend
}

nginx配置里 backend字符是用来替换行的标记
你可以定义为自己独特的字符即可

B服务器做个脚本做定期检查,需要root权限,比如五分钟:
*/5 * * * * root /Data/scripts/backend.check.sh >/dev/null


/Data/scripts/backend.check.sh
#!/bin/bash

file="/tmp/backend.log"
file2="/path/to/your/nginx.conf"

a=`grep backend $file`
b=`grep backend $file2`

if [ "$a" != "$b" ]; then
  sed -i "s|$b|$a|" $file2
  echo "reload";
  /Data/apps/nginx/sbin/nginx -s reload
fi


我们在A上可以加一个计划任务:

#report ip
*/3 * * * * daemon curl http://your/visit/url >/dev/null


梳理一下:
A服务器每3分钟访问 http://your/visit/url ,完成报告IP的任务
B服务器获取到IP后,写入临时文件,留给计划任务做对比用
B服务器每5分钟检查配置文件里的backend是否和临时文件里的一致
如果不一致,就替换为新的backend,然后重载nginx

这样,访问B服务器,就可以正常访问到A服务器了

【如果没有任何端口可开放】
可以访问http://www.aslibra.com/doc...
ssh -R1080:localhost:80 some-server

我们可以建立一个ssh连接,把B服务器端的1080端口,映射为本机的80端口
然后B服务器直接代理本机的1080端口也就是相当于访问A服务器的80端口了
不过,网络会随着ssh连接的中断而需要重建
使用NSURLSessionConfiguration可以设置使用代理服务器做请求:

NSString* proxyHost = @"1.2.3.4";
NSNumber* proxyPort = [NSNumber numberWithInt: 10888];

// Create an NSURLSessionConfiguration that uses the proxy
NSDictionary *proxyDict = @{
                            @"HTTPEnable"  : [NSNumber numberWithInt:1],
                            (NSString *)kCFStreamPropertyHTTPProxyHost  : proxyHost,
                            (NSString *)kCFStreamPropertyHTTPProxyPort  : proxyPort,
                            
                            @"HTTPSEnable" : [NSNumber numberWithInt:1],
                            (NSString *)kCFStreamPropertyHTTPSProxyHost : proxyHost,
                            (NSString *)kCFStreamPropertyHTTPSProxyPort : proxyPort,
                            };

NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration ephemeralSessionConfiguration];
configuration.connectionProxyDictionary = proxyDict;


其中,还可以设置HTTPAdditionalHeaders,解决请求头的问题:

NSString *userPasswordString = [NSString stringWithFormat:@"%@:%@", user, password];
NSData * userPasswordData = [userPasswordString dataUsingEncoding:NSUTF8StringEncoding];
NSString *base64EncodedCredential = [userPasswordData base64EncodedStringWithOptions:0];
NSString *authString = [NSString stringWithFormat:@"Basic %@", base64EncodedCredential];
NSString *userAgentString = @"AppName/com.example.app (iPhone 5s; iOS 7.0.2; Scale/2.0)";

configuration.HTTPAdditionalHeaders = @{@"Accept": @"application/json",
                                        @"Accept-Language": @"en",
                                        @"Authorization": authString,
                                        @"User-Agent": userAgentString};


Authorization是解决页面需要认证的情况,比如登录TP-link的路由器,提示你需要用户名和密码
而如果代理服务器需要验证,则可以加上一条类似的头信息,key值不一样
把Authorization 改为 Proxy-Authorization 即可

这个情况可以用curl了解到:

引用
curl -v baidu.com -x 1.2.3.4:10888 --proxy-user abc:xyz
* About to connect() to proxy 1.2.3.4 port 10888 (#0)
*   Trying 1.2.3.4... connected
* Connected to 1.2.3.4 (1.2.3.4) port 10888 (#0)
* Proxy auth using Basic with user 'abc'
> GET http://baidu.com HTTP/1.1
> Proxy-Authorization: Basic abc..xyz=
> User-Agent: curl/7.19.7 (i386-redhat-linux-gnu) libcurl/7.19.7 NSS/3.16.2.3 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2
> Host: baidu.com
> Accept: */*
> Proxy-Connection: Keep-Alive
>
* HTTP 1.0, assume close after body
< HTTP/1.0 200 OK


参考页面:
http://www.objc.io/issues/...
http://stackoverflow.com/q...
discuz获取真实ip的方法是这个:
source/class/discuz/discuz_application.php

private function _get_client_ip() {
  $ip = $_SERVER['REMOTE_ADDR'];
  if (isset($_SERVER['HTTP_CLIENT_IP']) && preg_match('/^([0-9]{1,3}\.){3}[0-9]{1,3}$/', $_SERVER['HTTP_CLIENT_IP'])) {
    $ip = $_SERVER['HTTP_CLIENT_IP'];
  } elseif(isset($_SERVER['HTTP_X_FORWARDED_FOR']) AND preg_match_all('#\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}#s', $_SERVER['HTTP_X_FORWARDED_FOR'], $matches)) {
    foreach ($matches[0] AS $xip) {
      if (!preg_match('#^(10|172\.16|192\.168)\.#', $xip)) {
        $ip = $xip;
        break;
      }
    }
  }
  return $ip;
}


也就是说默认用REMOTE_ADDR,如果有HTTP_CLIENT_IP或HTTP_X_FORWARDED_FOR,则用相应的指定的IP地址。
这个对于用ip来限制重试密码的方式来说,很危险,伪造一个CLIENT_IP或者X_FORWARDED_FOR就可以让discuz认为的独立的ip,从而脱离限制。
discuz也没有白名单机制去限制这两个参数的使用,所以是个很危险的漏洞。

防御方式:对使用CLIENT_IP或者X_FORWARDED_FOR限制

如果明确不使用代理方式部署服务器,那可以考虑禁用这两个参数。
如果用代理的方式部署,可以实施白名单机制。
PHP修改代码即可,判别REMOTE_ADDR白名单再启用这两个参数。

Nginx也可以有白名单的方式,编译需要添加参数:
--with-http_realip_module
使用说明:http://nginx.org/en/docs/h...

可以对比一下几个方式搭配:
1 不使用realip_module
2 使用realip_module

客户端模式:
A 伪造client-ip直接访问目标服务器
B 伪造client-ip访问代理服务器
C 代理服务器不在realip_module白名单
代理服务器设置
proxy_set_header        CLIENT-IP       $remote_addr;


为此,我们需要先修改PHP代码,以便获知PHP获得的参数:

private function _get_client_ip() {
  $ip = $_SERVER['REMOTE_ADDR'];
  if (isset($_GET['debug_ip'])) {
    exit('REMOTE_ADDR:'.$ip.' / CLIENT_IP:'.$_SERVER['HTTP_CLIENT_IP'].' / X_FORWARDED_FOR:'.$_SERVER['HTTP_X_FORWARDED_FOR']."\n");
  }
  $white_lists = array(
    '60.191.x.y',
    '123.157.x.y',
    '222.187.x.y',
    '121.40.x.y',
    );
  if (!in_array( $ip, $white_lists)) {
    return $ip;
  }
  if (isset($_SERVER['HTTP_CLIENT_IP']) && preg_match('/^([0-9]{1,3}\.){3}[0-9]{1,3}$/', $_SERVER['HTTP_CLIENT_IP'])) {
    $ip = $_SERVER['HTTP_CLIENT_IP'];
  } elseif(isset($_SERVER['HTTP_X_FORWARDED_FOR']) AND preg_match_all('#\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}#s', $_SERVER['HTTP_X_FORWARDED_FOR'], $matches)) {
    foreach ($matches[0] AS $xip) {
      if (!preg_match('#^(10|172\.16|192\.168)\.#', $xip)) {
        $ip = $xip;
        break;
      }
    }
  }
  return $ip;
}


测试组合结果:
域名和ip因为隐私做了替换
引用
1A

curl -H "host:www.aslibra.com" -H "CLIENT-IP:2.3.4.5" "dyw3.aslibra.com/?debug_ip=1"
REMOTE_ADDR:114.243.204.152 / CLIENT_IP:2.3.4.5 / X_FORWARDED_FOR:

1B

curl -H "host:www.aslibra.com" -H "CLIENT-IP:2.3.4.5" "dyw4.aslibra.com/?debug_ip=1"
REMOTE_ADDR:222.187.x.y / CLIENT_IP:114.243.204.152 / X_FORWARDED_FOR:

2A

curl -H "host:www.aslibra.com" -H "CLIENT-IP:2.3.4.5" "dyw3.aslibra.com/?debug_ip=1"
REMOTE_ADDR:114.243.204.152 / CLIENT_IP:2.3.4.5 / X_FORWARDED_FOR:

2B

curl -H "host:www.aslibra.com" -H "CLIENT-IP:2.3.4.5" "dyw4.aslibra.com/?debug_ip=1"
REMOTE_ADDR:114.243.204.152 / CLIENT_IP:114.243.204.152 / X_FORWARDED_FOR:

2C 222.187.x.y 不在nginx的白名单的情况

curl -H "host:www.aslibra.com" -H "CLIENT-IP:2.3.4.5" "dyw4.aslibra.com/?debug_ip=1"
REMOTE_ADDR:222.187.x.y / CLIENT_IP:114.243.204.152 / X_FORWARDED_FOR:


测试结果说明什么问题?
1A 客户端ip 和设定的ip都收到
1B 代理ip和客户端ip
2A 客户端ip和设定的ip
2B 客户端ip和客户端ip
2C 代理ip和客户端ip

说明,realip_module传递给PHP后端REMOTE_ADDR就是合法的CLIENT_IP,而CLIENT_IP却没有清空
那问题来了,它没法解决discuz检查CLIENT_IP的漏洞,如果检查就没戏
所以,PHP加一份白名单很有必要哦!
分页: 2/132 第一页 上页 1 2 3 4 5 6 7 8 9 10 下页 最后页 [ 显示模式: 摘要 | 列表 ]

阅读推荐

服务器相关推荐

开发相关推荐

应用软件推荐