私のCuteKeWebサイトはしばらくの間オンラインでしたが、以前にもアクセスログを作成しましたが、ログがまだ観察に役立たないことがわかったので、アクセスレコードデータベースを作成しました。しかし、過去数日間、URLを記録するときに問題を発見しました。
1.レコードURL
まず、URLとIPアドレスを記録する方法を見てみましょう。
1.1アクセスレコードモデル
アクセスレコードをデジタル化するため、アクセスレコードエンティティクラスを作成する必要があります。VistorLog
コードは次のとおりです。
@Entity
public class VisitorLog {
private static final long serialVersionUID = 1L;
@Id // 主键
@GeneratedValue(strategy = GenerationType.IDENTITY) // 自增长策略
private Long id; // 用户的唯一标识
@NotEmpty(message = "访问地址不能为空")
@Column(nullable = false)
private String url;
@NotEmpty(message = "访问方法不能为空")
@Column(nullable = false)
private String httpMethod;
@NotEmpty(message = "IP地址不能为空")
@Column(nullable = false)
private String ip;
@NotEmpty(message = "IP地址映射的真实不能为空")
@Column(nullable = false)
private String trueAddress;
@Column(nullable = false) // 映射为字段,值不能为空
@org.hibernate.annotations.CreationTimestamp // 由数据库自动创建时间
private Timestamp visitTime;
@NotEmpty(message = "后台访问方法不能为空")
@Column(nullable = false)
private String classMethod;
@NotEmpty(message = "访问方法参数")
@Column(nullable = false)
private String getClassMethodArgs;
protected VisitorLog(){
}
public VisitorLog(String url, String httpMethod, String ip, String trueAddress,String classMethod, String getClassMethodArgs) {
this.url = url;
this.httpMethod = httpMethod;
this.ip = ip;
this.trueAddress= trueAddress;
this.classMethod = classMethod;
this.getClassMethodArgs = getClassMethodArgs;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getHttpMethod() {
return httpMethod;
}
public void setHttpMethod(String httpMethod) {
this.httpMethod = httpMethod;
}
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
public String getClassMethod() {
return classMethod;
}
public void setClassMethod(String classMethod) {
this.classMethod = classMethod;
}
public String getGetClassMethodArgs() {
return getClassMethodArgs;
}
public void setGetClassMethodArgs(String getClassMethodArgs) {
this.getClassMethodArgs = getClassMethodArgs;
}
}
1.2 SpringAOPの使用
gradlespring-boot-starter-aop
に依存関係を追加した後、次のように設計できます。
- エントリポイント:各
Controller
リクエストメソッドの各メソッド
@Pointcut("execution(public * com.cuteke.spring.boot.blog.controlller.*.*(..))")
public void log() {
};
- 通知:ここで選択し
前置通知
ます。他の通知も選択できます
@Before("log()")
public void doBefore(JoinPoint joinPoint) {
....
}
- Get HttpServletRequest:リクエストコンテキストから取得します
HttpServertRequest
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
- 各属性を取得する:取得したら、
HttpServertRequest
そのメソッドを呼び出すことで各属性を取得できますVisitLog
:
String url=new String(request.getRequestURL());
String method=request.getMethod();
String ip=IpUtil.getClinetIpByReq(request);
String class_method=joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName();
String args= Arrays.toString(joinPoint.getArgs());
logger.info("url={} method={} ip={} class_method={} args={}", url, method
, ip, class_method
, joinPoint.getArgs());
VisitorLog visitorLog=new VisitorLog(url,method,ip,IpUtil.getAddressByIP(ip),class_method,args);
vistorLogService.saveVistorLog(visitorLog);
IpUtil
これは、ipを処理するためのツールクラスです。コアアイデアは、getRemoteAddr()
メソッドとプロキシipの除外によって実現されます。これについては、残りの章で説明します。Baiduも簡単に見つけることができます。
2.URLが一致しません
ウェブサイトは数週間オンラインでしたが、下の図1に示すように、データに非常に奇妙な記録が見つかりました。
赤い線で変なURLを描いてみたのですが、見つけたのでしょうか?トラブルの原因となるこれらのURLはすべて外国人であり、海外でもトラブルを起こしたい!
2.1プロキシを使用していますか?
エージェントには2つのタイプがあります。
- フォワードプロキシ:クライアントはプロキシサーバーを構成する必要があり、代わりにプロキシサーバーがアクセスするため、URLは通常変更されません
- リバースプロキシ:クライアントはプロキシの存在を知りません。URLのURLにアクセスすると、リバースプロキシサーバーを通過し、次にリバースプロキシサーバーが対応するサーバーにアクセスします。これは通常、
負荷分散に使用され、URLは通常変更されません。
実際、プロキシを使用している場合、サーバーの存在、URLの変更、またはその他の操作がユーザーに知られていないため、この状況が発生する可能性があります。海外でこの状況で識別できる限り、URLがIPアドレスの解決に使用されることはわかっています。のサーバーIPアドレスは、URLが私のWebサイトのURLであるかどうかに関係なく、私のWebサイトにアクセスできます。
2.2ホストの練習
前述のように、サーバーのIPアドレスが解析されている限り、URLが正しいかどうかに関係なく、このマシンで練習します。C:\ Windows \ System32 \ drivers \ etcにHOSTファイルがあることがわかっています。URLに対応するIPを変更するだけで済みます。分析を完了することができます。コードは次のように表示されます。
# localhost name resolution is handled within DNS itself.
127.0.0.1 localhost
# ::1 localhost
127.0.0.1 www.cuteke.cn
ここで、自分のWebサイトのドメイン名をローカルアドレスに解決します。このコンピューターで自分のWebサイトも開きますが、内部のコンテンツが異なります。ブラウザーに入力すると、www.cuteke.cn
次のようなページが見つかりました。
このマシンのトップ記事は公開ウェブサイトのトップ記事とは異なるため、このページはローカルサーバーによって表示されるページです。同時に、ローカルデータベースのアクセスレコードを確認します。
最後の2行で、URLがだけでlocalhost
なくwww.cuteke.cn
、私たちの考えを検証していることがわかります。
HOSTSファイルを変更した後、アクセスしたURLがまだ元のアドレスに解決されている場合は、システムDNSとブラウザーのDNSキャッシュをクリアすることを忘れないでください
HOSTSファイルの変更は可能性の1つに過ぎず、Http Hostヘッダー攻撃である可能性が非常に高いです。次の章では、その原理と具体的な防御策について説明します。
参照
[1] Spring Boot Advanced Web Advanced
[2]フォワードプロキシとリバースプロキシ[概要]