Chủ Nhật, 5 tháng 5, 2019

DDoS Protection With IPtables: The Ultimate Guide


copy from source https://javapipe.com/blog/iptables-ddos-protection/

DDoS Protection With IPtables: The Ultimate Guide

iptables DDoS Protection
There are different ways of building your own anti-DDoS rules for iptables. We will be discussing the most effective iptables DDoS protection methods in this comprehensive tutorial.
This guide will teach you how to:
  1. Select the best iptables table and chain to stop DDoS attacks
  2. Tweak your kernel settings to mitigate the effects of DDoS attacks
  3. Use iptables to block most TCP-based DDoS attacks
  4. Use iptables SYNPROXY to block SYN floods
Please note that this article is written for professionals who deal with Linux servers on a daily basis.
If you just want to protect your online application from DDoS attacks, you can use our remote protection, a VPS with DDoS protection or a DDoS protected bare metal server.
While one can do a lot with iptables to block DDoS attacks, there isn’t a way around actual hardware firewalls (we recently reviewed RioRey DDoS mitigation hardware) to detect and stop large DDoS floods.
However, it isn’t impossible to filter most bad traffic at line rate using iptables!
We’ll only cover protection from TCP-based attacks. Most UDP-based attacks are amplified reflection attacks that will exhaust the network interface card of any common server.
The only mitigation approach that makes sense against these types of attacks is to block them at the edge or core network or even at the carrier already.
Did you know we now offer unmetered bandwidth VPS plans with DDoS protection in Chicago, Illinois and Bucharest, Romania?
If they are able to reach your server, there isn’t much you can do against those multi-Gbit/s attacks except to move to a DDoS protected network.
anti-DDoS iptables

What Is IPtables?

netfilter iptables (soon to be replaced by nftables) is a user-space command line utility to configure kernel packet filtering rules developed by netfilter.
It’s the default firewall management utility on Linux systems – everyone working with Linux systems should be familiar with it or have at least heard of it.
iptables can be used to filter certain packets, block source or destination ports and IP addresses, forward packets via NAT and a lot of other things.
Most commonly it’s used to block destination ports and source IP addresses.

Why Your IPtables Anti-DDoS Rules Suck

To understand why your current iptables rules to prevent DDoS attacks suck, we first have to dig into how iptables works.
iptables is a command line tool used to set up and control the tables of IP packet filter rules. There are different tables for different purposes.

IPtables Tables

Filter: The filter table is the default and most commonly used table that rules go to if you don’t use the -t (–table) option.
Nat: This table is used for Network Address Translation (NAT). If a packet creates a new connection, the nat table gets checked for rules.
Mangle: The mangle table is used to modify or mark packets and their header information.
Raw: This table’s purpose is mainly to exclude certain packets from connection tracking using the NOTRACK target.
As you can see there are four different tables on an average Linux system that doesn’t have non-standard kernel modules loaded. Each of these tables supports a different set of iptables chains.

IPtables Chains

PREROUTING: raw, nat, mangle
  • Applies to packets that enter the network interface card (NIC)
INPUT: filter, mangle
  • Applies to packets destined to a local socket
FORWARD: filter, mangle
  • Applies to packets that are being routed through the server
OUTPUT: raw, filter, nat, mangle
  • Applies to packets that the server sends (locally generated)
POSTROUTING: nat, mangle
  • Applies to packets that leave the server
Depending on what kind of packets you want to block or modify, you select a certain iptables table and a chain that the selected table supports.
Of course, we’re still missing an explanation of iptables targets (ACCEPT, DROP, REJECT, etc.), but we’re assuming that if you’re reading this article, you already know how to deal with iptables.
We’re going to explain why your iptables rules suck to stop DDoS and not teach you how to use iptables. Let’s get back to that.
If you want to block a DDoS attack with iptables, performance of the iptables rules is extremely important. Most TCP-based DDoS attack types use a high packet rate, meaning the sheer number of packets per second is what causes the server to go down.
That’s why you want to make sure that you can process and block as many packets per second as possible.
You’ll find that most if not all guides on how to block DDoS attacks using iptables use the filter table and the INPUT chain for anti-DDoS rules.
The issue with this approach is that the INPUT chain is only processed after the PREROUTING and FORWARD chains and therefore only applies if the packet doesn’t match any of these two chains.
This causes a delay in the filtering of the packet which consumes resources. In conclusion, to make our rules as effective as possible, we need to move our anti-DDoS rules as far up the chains as possible.
The first chain that can apply to a packet is the PREROUTING chain, so ideally we’ll want to filter the bad packets in this chain already.
However, the filter table doesn’t support the PREROUTING chain. To get around this problem, we can simply use the mangle table instead of the filter table for our anti-DDoS iptables rules.
It supports most if not all rules that the filter table supports while also supporting all iptables chains.
So you want to know why your iptables DDoS protection rules suck? It’s because you use the filter table and the INPUT chain to block the bad packets!
The best solution to dramatically increase the performance of your iptables rules and therefore the amount of (TCP) DDoS attack traffic they can filter is to use the mangle table and the PREROUTING chain!

The Best Linux Kernel Settings to Mitigate DDoS

Another common mistake is that people don’t use optimized kernel settings to better mitigate the effects of DDoS attacks.
Note that this guide focuses on CentOS 7 as the operating system of choice. CentOS 7 includes a recent version of iptables and support of the new SYNPROXY target.
We won’t cover every single kernel setting that you need to adjust in order to better mitigate DDoS with iptables.
Instead, we provide a set of CentOS 7 kernel settings that we would use. Just put the below in your /etc/sysctl.conf file and apply the settings with sysctl -p.

Anti-DDoS Kernel Settings (sysctl.conf)

kernel.printk = 4 4 1 7 
kernel.panic = 10 
kernel.sysrq = 0 
kernel.shmmax = 4294967296 
kernel.shmall = 4194304 
kernel.core_uses_pid = 1 
kernel.msgmnb = 65536 
kernel.msgmax = 65536 
vm.swappiness = 20 
vm.dirty_ratio = 80 
vm.dirty_background_ratio = 5 
fs.file-max = 2097152 
net.core.netdev_max_backlog = 262144 
net.core.rmem_default = 31457280 
net.core.rmem_max = 67108864 
net.core.wmem_default = 31457280 
net.core.wmem_max = 67108864 
net.core.somaxconn = 65535 
net.core.optmem_max = 25165824 
net.ipv4.neigh.default.gc_thresh1 = 4096 
net.ipv4.neigh.default.gc_thresh2 = 8192 
net.ipv4.neigh.default.gc_thresh3 = 16384 
net.ipv4.neigh.default.gc_interval = 5 
net.ipv4.neigh.default.gc_stale_time = 120 
net.netfilter.nf_conntrack_max = 10000000 
net.netfilter.nf_conntrack_tcp_loose = 0 
net.netfilter.nf_conntrack_tcp_timeout_established = 1800 
net.netfilter.nf_conntrack_tcp_timeout_close = 10 
net.netfilter.nf_conntrack_tcp_timeout_close_wait = 10 
net.netfilter.nf_conntrack_tcp_timeout_fin_wait = 20 
net.netfilter.nf_conntrack_tcp_timeout_last_ack = 20 
net.netfilter.nf_conntrack_tcp_timeout_syn_recv = 20 
net.netfilter.nf_conntrack_tcp_timeout_syn_sent = 20 
net.netfilter.nf_conntrack_tcp_timeout_time_wait = 10 
net.ipv4.tcp_slow_start_after_idle = 0 
net.ipv4.ip_local_port_range = 1024 65000 
net.ipv4.ip_no_pmtu_disc = 1 
net.ipv4.route.flush = 1 
net.ipv4.route.max_size = 8048576 
net.ipv4.icmp_echo_ignore_broadcasts = 1 
net.ipv4.icmp_ignore_bogus_error_responses = 1 
net.ipv4.tcp_congestion_control = htcp 
net.ipv4.tcp_mem = 65536 131072 262144 
net.ipv4.udp_mem = 65536 131072 262144 
net.ipv4.tcp_rmem = 4096 87380 33554432 
net.ipv4.udp_rmem_min = 16384 
net.ipv4.tcp_wmem = 4096 87380 33554432 
net.ipv4.udp_wmem_min = 16384 
net.ipv4.tcp_max_tw_buckets = 1440000 
net.ipv4.tcp_tw_recycle = 0 
net.ipv4.tcp_tw_reuse = 1 
net.ipv4.tcp_max_orphans = 400000 
net.ipv4.tcp_window_scaling = 1 
net.ipv4.tcp_rfc1337 = 1 
net.ipv4.tcp_syncookies = 1 
net.ipv4.tcp_synack_retries = 1 
net.ipv4.tcp_syn_retries = 2 
net.ipv4.tcp_max_syn_backlog = 16384 
net.ipv4.tcp_timestamps = 1 
net.ipv4.tcp_sack = 1 
net.ipv4.tcp_fack = 1 
net.ipv4.tcp_ecn = 2 
net.ipv4.tcp_fin_timeout = 10 
net.ipv4.tcp_keepalive_time = 600 
net.ipv4.tcp_keepalive_intvl = 60 
net.ipv4.tcp_keepalive_probes = 10 
net.ipv4.tcp_no_metrics_save = 1 
net.ipv4.ip_forward = 0 
net.ipv4.conf.all.accept_redirects = 0 
net.ipv4.conf.all.send_redirects = 0 
net.ipv4.conf.all.accept_source_route = 0 
net.ipv4.conf.all.rp_filter = 1
These sysctl.conf settings help to maximize the performance of your server under DDoS as well as the effectiveness of the iptables rules that we’re going to provide in this guide.

The Actual IPtables Anti-DDoS Rules

Considering you now know that you need to use the mangle table and the PREROUTING chain as well as optimized kernel settings to mitigate the effects of DDoS attacks, we’ll now move on to a couple of example rules to mitigate most TCP DDoS attacks.
DDoS attacks are complex.
There are many different types of DDoS and it’s close to impossible to maintain signature-based rules against all of them.
But luckily there is something called connection tracking (nf_conntrack kernel module), which can help us to mitigate almost any TCP-based DDoS attack that doesn’t use SYN packets that seem legitimate.
This includes all types of ACK and SYN-ACK DDoS attacks as well as DDoS attacks that use bogus TCP flags.
We’ll start with just five simple iptables rules that will already drop many TCP-based DDoS attacks.

Block Invalid Packets

iptables -t mangle -A PREROUTING -m conntrack --ctstate INVALID -j DROP
This rule blocks all packets that are not a SYN packet and don’t belong to an established TCP connection.

Block New Packets That Are Not SYN

iptables -t mangle -A PREROUTING -p tcp ! --syn -m conntrack --ctstate NEW -j DROP
This blocks all packets that are new (don’t belong to an established connection) and don’t use the SYN flag. This rule is similar to the “Block Invalid Packets” one, but we found that it catches some packets that the other one doesn’t.

Block Uncommon MSS Values

iptables -t mangle -A PREROUTING -p tcp -m conntrack --ctstate NEW -m tcpmss ! --mss 536:65535 -j DROP
The above iptables rule blocks new packets (only SYN packets can be new packets as per the two previous rules) that use a TCP MSS value that is not common. This helps to block dumb SYN floods.

Block Packets With Bogus TCP Flags

iptables -t mangle -A PREROUTING -p tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG NONE -j DROP 
iptables -t mangle -A PREROUTING -p tcp --tcp-flags FIN,SYN FIN,SYN -j DROP 
iptables -t mangle -A PREROUTING -p tcp --tcp-flags SYN,RST SYN,RST -j DROP 
iptables -t mangle -A PREROUTING -p tcp --tcp-flags FIN,RST FIN,RST -j DROP 
iptables -t mangle -A PREROUTING -p tcp --tcp-flags FIN,ACK FIN -j DROP 
iptables -t mangle -A PREROUTING -p tcp --tcp-flags ACK,URG URG -j DROP 
iptables -t mangle -A PREROUTING -p tcp --tcp-flags ACK,FIN FIN -j DROP 
iptables -t mangle -A PREROUTING -p tcp --tcp-flags ACK,PSH PSH -j DROP 
iptables -t mangle -A PREROUTING -p tcp --tcp-flags ALL ALL -j DROP 
iptables -t mangle -A PREROUTING -p tcp --tcp-flags ALL NONE -j DROP 
iptables -t mangle -A PREROUTING -p tcp --tcp-flags ALL FIN,PSH,URG -j DROP 
iptables -t mangle -A PREROUTING -p tcp --tcp-flags ALL SYN,FIN,PSH,URG -j DROP 
iptables -t mangle -A PREROUTING -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP
The above ruleset blocks packets that use bogus TCP flags, ie. TCP flags that legitimate packets wouldn’t use.

Block Packets From Private Subnets (Spoofing)

iptables -t mangle -A PREROUTING -s 224.0.0.0/3 -j DROP 
iptables -t mangle -A PREROUTING -s 169.254.0.0/16 -j DROP 
iptables -t mangle -A PREROUTING -s 172.16.0.0/12 -j DROP 
iptables -t mangle -A PREROUTING -s 192.0.2.0/24 -j DROP 
iptables -t mangle -A PREROUTING -s 192.168.0.0/16 -j DROP 
iptables -t mangle -A PREROUTING -s 10.0.0.0/8 -j DROP 
iptables -t mangle -A PREROUTING -s 0.0.0.0/8 -j DROP 
iptables -t mangle -A PREROUTING -s 240.0.0.0/5 -j DROP 
iptables -t mangle -A PREROUTING -s 127.0.0.0/8 ! -i lo -j DROP
These rules block spoofed packets originating from private (local) subnets. On your public network interface you usually don’t want to receive packets from private source IPs.
These rules assume that your loopback interface uses the 127.0.0.0/8 IP space.
These five sets of rules alone already block many TCP-based DDoS attacks at very high packet rates.
With the kernel settings and rules mentioned above, you’ll be able to filter ACK and SYN-ACK attacks at line rate.

Additional Rules

iptables -t mangle -A PREROUTING -p icmp -j DROP
This drops all ICMP packets. ICMP is only used to ping a host to find out if it’s still alive. Because it’s usually not needed and only represents another vulnerability that attackers can exploit, we block all ICMP packets to mitigate Ping of Death (ping flood), ICMP flood and ICMP fragmentation flood.
iptables -A INPUT -p tcp -m connlimit --connlimit-above 80 -j REJECT --reject-with tcp-reset
This iptables rule helps against connection attacks. It rejects connections from hosts that have more than 80 established connections. If you face any issues you should raise the limit as this could cause troubles with legitimate clients that establish a large number of TCP connections.
iptables -A INPUT -p tcp -m conntrack --ctstate NEW -m limit --limit 60/s --limit-burst 20 -j ACCEPT 
iptables -A INPUT -p tcp -m conntrack --ctstate NEW -j DROP
Limits the new TCP connections that a client can establish per second. This can be useful against connection attacks, but not so much against SYN floods because the usually use an endless amount of different spoofed source IPs.
iptables -t mangle -A PREROUTING -f -j DROP
This rule blocks fragmented packets. Normally you don’t need those and blocking fragments will mitigate UDP fragmentation flood. But most of the time UDP fragmentation floods use a high amount of bandwidth that is likely to exhaust the capacity of your network card, which makes this rule optional and probably not the most useful one.
iptables -A INPUT -p tcp --tcp-flags RST RST -m limit --limit 2/s --limit-burst 2 -j ACCEPT 
iptables -A INPUT -p tcp --tcp-flags RST RST -j DROP
This limits incoming TCP RST packets to mitigate TCP RST floods. Effectiveness of this rule is questionable.

Mitigating SYN Floods With SYNPROXY

SYNPROXY is a new target of iptables that has been added in Linux kernel version 3.12 and iptables 1.4.21. CentOS 7 backported the feature and it’s available in its 3.10 default kernel.
The purpose of SYNPROXY is to check whether the host that sent the SYN packet actually establishes a full TCP connection or just does nothing after it sent the SYN packet.
If it does nothing, it discards the packet with minimal performance impact.
While the iptables rules that we provided above already block most TCP-based attacks, the attack type that can still slip through them if sophisticated enough is a SYN flood.
It’s important to note that the performance of the rules will always be better if we find a certain pattern or signature to block, such as packet length (-m length), TOS (-m tos), TTL (-m ttl) or strings and hex values (-m string and -m u32 for the more advanced users).
But in some rare cases that’s not possible or at least not easy to achieve. So, in these cases, you can make use of SYNPROXY.
Here are iptables SYNPROXY rules that help mitigate SYN floods that bypass our other rules:
iptables -t raw -A PREROUTING -p tcp -m tcp --syn -j CT --notrack 
iptables -A INPUT -p tcp -m tcp -m conntrack --ctstate INVALID,UNTRACKED -j SYNPROXY --sack-perm --timestamp --wscale 7 --mss 1460 
iptables -A INPUT -m conntrack --ctstate INVALID -j DROP
These rules apply to all ports. If you want to use SYNPROXY only on certain TCP ports that are active (recommended – also you should block all TCP ports that are not in use using the mangle table and PREROUTING chain), you can just add –dport 80 to each of the rules if you want to use SYNPROXY on port 80 only.
To verify that SYNPROXY is working, you can do watch -n1 cat /proc/net/stat/synproxy. If the values change when you establish a new TCP connection to the port you use SYNPROXY on, it works.

The Complete IPtables Anti-DDoS Rules

If you don’t want to copy & paste each single rule we discussed in this article, you can use the below ruleset for basic DDoS protection of your Linux server.
### 1: Drop invalid packets ### 
/sbin/iptables -t mangle -A PREROUTING -m conntrack --ctstate INVALID -j DROP  

### 2: Drop TCP packets that are new and are not SYN ### 
/sbin/iptables -t mangle -A PREROUTING -p tcp ! --syn -m conntrack --ctstate NEW -j DROP 
 
### 3: Drop SYN packets with suspicious MSS value ### 
/sbin/iptables -t mangle -A PREROUTING -p tcp -m conntrack --ctstate NEW -m tcpmss ! --mss 536:65535 -j DROP  

### 4: Block packets with bogus TCP flags ### 
/sbin/iptables -t mangle -A PREROUTING -p tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG NONE -j DROP 
/sbin/iptables -t mangle -A PREROUTING -p tcp --tcp-flags FIN,SYN FIN,SYN -j DROP 
/sbin/iptables -t mangle -A PREROUTING -p tcp --tcp-flags SYN,RST SYN,RST -j DROP 
/sbin/iptables -t mangle -A PREROUTING -p tcp --tcp-flags FIN,RST FIN,RST -j DROP 
/sbin/iptables -t mangle -A PREROUTING -p tcp --tcp-flags FIN,ACK FIN -j DROP 
/sbin/iptables -t mangle -A PREROUTING -p tcp --tcp-flags ACK,URG URG -j DROP 
/sbin/iptables -t mangle -A PREROUTING -p tcp --tcp-flags ACK,FIN FIN -j DROP 
/sbin/iptables -t mangle -A PREROUTING -p tcp --tcp-flags ACK,PSH PSH -j DROP 
/sbin/iptables -t mangle -A PREROUTING -p tcp --tcp-flags ALL ALL -j DROP 
/sbin/iptables -t mangle -A PREROUTING -p tcp --tcp-flags ALL NONE -j DROP 
/sbin/iptables -t mangle -A PREROUTING -p tcp --tcp-flags ALL FIN,PSH,URG -j DROP 
/sbin/iptables -t mangle -A PREROUTING -p tcp --tcp-flags ALL SYN,FIN,PSH,URG -j DROP 
/sbin/iptables -t mangle -A PREROUTING -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP  

### 5: Block spoofed packets ### 
/sbin/iptables -t mangle -A PREROUTING -s 224.0.0.0/3 -j DROP 
/sbin/iptables -t mangle -A PREROUTING -s 169.254.0.0/16 -j DROP 
/sbin/iptables -t mangle -A PREROUTING -s 172.16.0.0/12 -j DROP 
/sbin/iptables -t mangle -A PREROUTING -s 192.0.2.0/24 -j DROP 
/sbin/iptables -t mangle -A PREROUTING -s 192.168.0.0/16 -j DROP 
/sbin/iptables -t mangle -A PREROUTING -s 10.0.0.0/8 -j DROP 
/sbin/iptables -t mangle -A PREROUTING -s 0.0.0.0/8 -j DROP 
/sbin/iptables -t mangle -A PREROUTING -s 240.0.0.0/5 -j DROP 
/sbin/iptables -t mangle -A PREROUTING -s 127.0.0.0/8 ! -i lo -j DROP  

### 6: Drop ICMP (you usually don't need this protocol) ### 
/sbin/iptables -t mangle -A PREROUTING -p icmp -j DROP  

### 7: Drop fragments in all chains ### 
/sbin/iptables -t mangle -A PREROUTING -f -j DROP  

### 8: Limit connections per source IP ### 
/sbin/iptables -A INPUT -p tcp -m connlimit --connlimit-above 111 -j REJECT --reject-with tcp-reset  

### 9: Limit RST packets ### 
/sbin/iptables -A INPUT -p tcp --tcp-flags RST RST -m limit --limit 2/s --limit-burst 2 -j ACCEPT 
/sbin/iptables -A INPUT -p tcp --tcp-flags RST RST -j DROP  

### 10: Limit new TCP connections per second per source IP ### 
/sbin/iptables -A INPUT -p tcp -m conntrack --ctstate NEW -m limit --limit 60/s --limit-burst 20 -j ACCEPT 
/sbin/iptables -A INPUT -p tcp -m conntrack --ctstate NEW -j DROP  

### 11: Use SYNPROXY on all ports (disables connection limiting rule) ### 
# Hidden - unlock content above in "Mitigating SYN Floods With SYNPROXY" section

Bonus Rules

Here are some more iptables rules that are useful to increase the overall security of a Linux server:
### SSH brute-force protection ### 
/sbin/iptables -A INPUT -p tcp --dport ssh -m conntrack --ctstate NEW -m recent --set 
/sbin/iptables -A INPUT -p tcp --dport ssh -m conntrack --ctstate NEW -m recent --update --seconds 60 --hitcount 10 -j DROP  

### Protection against port scanning ### 
/sbin/iptables -N port-scanning 
/sbin/iptables -A port-scanning -p tcp --tcp-flags SYN,ACK,FIN,RST RST -m limit --limit 1/s --limit-burst 2 -j RETURN 
/sbin/iptables -A port-scanning -j DROP

Conclusion

This tutorial demonstrates some of the most powerful and effective methods to stop DDoS attacks using iptables.
We’ve successfully mitigated DDoS attacks that peaked at multiple million packets per second using these iptables rules.
Every single guide on the same topic that we had researched provided inefficient methods to stop DDoS traffic or only a very limited number of iptables rules.
If used correctly, iptables is an extremely powerful tool that’s able to block different types of DDoS attacks at line-rate of 1GigE NICs and close to line-rate of 10GigE NICs.
Don’t underestimate the power of iptables!

Thứ Tư, 24 tháng 4, 2019

Cách Đăng Ký Adsense /Cách xác minh tài khoản GA

Copy from Facebook 
Vinh Hoang Duc

Chia Sẻ Kiến Thức về Google Adsense:
- Xin chào các bác. Nói trc mình ko phải Chuyên Gia hướng dẫn. Mà đơn giản là mình tự Seo, tự chơi Adsense. Hầu hết đều là Tự Làm nên không thể tránh khỏi những Sai Lầm đáng tiếc.
- Vì vậy những Sai Lầm của mình sẽ là Bài Học cho Newbie, tránh mất tiền Ngu  Đây là những kinh nghiệm 100% Thực Tế chứ không phải Lý Thuyết trong sách vở nhé. Hy vọng có ích với các bác 
*** 1, Cách Đăng Ký Adsense ***
- Như các bác đã biết, Con Gà của mình mới lăn ra chết trong thời gian vừa qua. Vì vậy mình có lấy vài con PBN để đem đi đăng ký (PBN khoảng 400-500 index, nội dung như *** vì ngày trc mình có mở bán VIP PBN nên bị ae Spam) ==> Lý do Google đưa ra là:
1) Nội dung cóp nhặt
2) Nội dung ko mang lại giá trị
- Sau đó mình lấy 1 con PBN khác (Chỉ có vài chục bài viết, do mình tự viết, ko Copy, 1 ngày chỉ khoảng 20-30 view thôi) ==> Kết Quả: Được Duyệt ngay lập tức.
===> Bài học cho các bác: Để đăng ký thành công Adsense: Chúng ta ko cần nhiều index, nhiều traffic. Chỉ cần nội dung Gốc, Ko Copy, Ko Spin các kiểu. Mang lại giá trị cho người dùng là đủ.
- Ngoài ra: web cần có những trang quan trọng như: Giới Thiệu, Điều Khoản, Liên Hệ. Giao diện dễ nhìn, điều hướng Menu hợp lý...
*** 2, Cách xác minh tài khoản GA ***
- UPDATE mới nhất 2019: Ở thời điểm hiện tại, sau khi đăng ký thành công GA và đạt ngưỡng 10$ chúng ta phải xác minh Danh Tính bằng CMND/Thẻ Căn Cước -> Rồi mới đến bước xác minh địa chỉ (PIN) - Lằng nhằng vkl.
- Nếu xác minh mà Tạch 3 lần thì coi như chết GÀ. và Đen như Chó. Mình gửi ảnh xác minh bị Từ Chối luôn. Lý do là:
1) Ảnh quá mờ
2) Ảnh quá nhỏ.
==> Bài học cho các bác khi chụp ảnh CMND/ Thẻ Căn Cước để xác minh danh tính như sau:
- Chụp ảnh gần gần chút sao cho to, rõ ràng, nhưng đặc biệt lưu ý: PHẢI CHỤP ẢNH NHÌN RÕ CẢ VIỀN nhé.
- Ko bật Flash, ảnh ko bị nhòe, bị mờ,... Tốt nhất là chụp vào ban ngày, nắng to, ko dùng app hỗ trợ. Nhớ là phải bật HD hoặc Full HD.
- Giữ nguyên dung lượng gốc, đừng nén, đừng chỉnh sửa, thay đổi, thêm bớt cái j.
- Vấn đề Địa Chỉ trong CMND có cần TRÙNG với Địa Chỉ nhận PIN đang là thắc mắc chưa đc giải đáp. (Khi nào mình xác minh thành công thì mới biết đc)
- Các bác lưu ý để có thể tự xác minh. Nếu đi thuê thì mất vài trăm K đấy. Sau khi xác minh danh tính xong qua bước nhận PIN thì đi thuê cũng đc. Vì nó rẻ. Khoảng 100k thôi.
*** 3, Cách kiếm tiền với Adsense ***
- Traffic thực, nội dung tốt. Nhiều view thì sẽ nhiều tiền. Nên tuân thủ theo chính sách của Google và tham khảo các đề xuất, hướng dẫn tăng doanh thu của nó.
- Mọi hành vi vi phạm, gian lận có thể giúp bạn kiếm đc Nhiều Tiền hơn bt. Nhưng bạn có thể Chết bất cứ lúc nào. Kể cả bạn chơi đúng Luật bạn cũng có thể Chết. Vì vậy lựa chọn chơi theo cách nào là ở bạn 

Chủ Nhật, 7 tháng 4, 2019

convert ppt,pptx, doc, docx to pdf with microsoft office programmatically (c#)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using Microsoft.Office.Interop.PowerPoint;
using Microsoft.Office.Interop.Word;
using Microsoft.Office.Core;
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            //convertDoc();
            convertPpt();


        }
        static void convertDoc()
        {
            // Create a new Microsoft Word application object
            Microsoft.Office.Interop.Word.Application word = new Microsoft.Office.Interop.Word.Application();

            // C# doesn't have optional arguments so we'll need a dummy value
            object oMissing = System.Reflection.Missing.Value;

            // Get list of Word files in specified directory
            DirectoryInfo dirInfo = new DirectoryInfo(@"E:\copy");
            string fileType = "doc";
            FileInfo[] wordFiles = dirInfo.GetFiles("*." + fileType, SearchOption.AllDirectories);

            word.Visible = false;
            word.ScreenUpdating = false;
            System.Console.WriteLine("total " + wordFiles.Length);
            int count = 0;
            StringBuilder strBuilder = new StringBuilder();
            foreach (FileInfo wordFile in wordFiles)
            {
                try
                {
                    // Cast as Object for word Open method
                    Object filename = (Object)wordFile.FullName;
                    strBuilder.Append("start " + count + "/" + wordFiles.Length + " " + wordFile.FullName + Environment.NewLine);
                    System.Console.WriteLine("start " + count + "/" + wordFiles.Length + " " + wordFile.FullName);
                    // Use the dummy value as a placeholder for optional arguments
                    Document doc = word.Documents.Open(ref filename, ref oMissing,
                        ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing,
                        ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing,
                        ref oMissing, ref oMissing, ref oMissing, ref oMissing);
                    //doc.Activate();

                    object outputFileName = wordFile.FullName.Replace("." + fileType, ".pdf");
                    object fileFormat = WdSaveFormat.wdFormatPDF;

                    // Save document into PDF Format
                    doc.SaveAs(ref outputFileName,
                        ref fileFormat, ref oMissing, ref oMissing,
                        ref oMissing, ref oMissing, ref oMissing, ref oMissing,
                        ref oMissing, ref oMissing, ref oMissing, ref oMissing,
                        ref oMissing, ref oMissing, ref oMissing, ref oMissing);
                    strBuilder.Append("end " + count + "/" + wordFiles.Length + " " + wordFile.FullName + Environment.NewLine);
                    System.Console.WriteLine("end " + count + "/" + wordFiles.Length + " " + wordFile.FullName);
                    count++;
                    // Close the Word document, but leave the Word application open.
                    // doc has to be cast to type _Document so that it will find the
                    // correct Close method.             
                    object saveChanges = WdSaveOptions.wdDoNotSaveChanges;
                    ((_Document)doc).Close(ref saveChanges, ref oMissing, ref oMissing);
                    doc = null;
                }
                catch (Exception ex)
                {
                    strBuilder.Append(wordFile.FullName + " " + ex.Message);
                    System.Console.WriteLine(wordFile.FullName + " " + ex.Message);
                }
                // word has to be cast to type _Application so that it will find
                // the correct Quit method.
             
            }
            ((Microsoft.Office.Interop.Word.Application)word).Quit(ref oMissing, ref oMissing, ref oMissing);
            word = null;
            File.WriteAllText(@"E:\convert-" + fileType + ".txt", strBuilder.ToString());
            System.Console.WriteLine("finish");
            System.Console.ReadLine();
        }
        static void convertPpt()
        {
            // Create a new Microsoft Word application object
            Microsoft.Office.Interop.PowerPoint.Application word = new Microsoft.Office.Interop.PowerPoint.Application();

            // C# doesn't have optional arguments so we'll need a dummy value
            object oMissing = System.Reflection.Missing.Value;

            // Get list of Word files in specified directory
            DirectoryInfo dirInfo = new DirectoryInfo(@"E:\copy");
            dirInfo = new DirectoryInfo(@"E:\copy\hệ điều hành_đỗ văn uy_dhbkhn\lecture");
            string fileType = "pptx";
            FileInfo[] wordFiles = dirInfo.GetFiles("*." + fileType, SearchOption.AllDirectories);
            System.Console.WriteLine("total " + wordFiles.Length);
            int count = 0;
            //word.Visible = false;
            //word.ScreenUpdating = false;
            StringBuilder strBuilder = new StringBuilder();
            foreach (FileInfo wordFile in wordFiles)
            {
                Presentation doc = null;
                try
                {
                    // Cast as Object for word Open method
                    Object filename = (Object)wordFile.FullName;

                    strBuilder.Append("start " + count + "/" + wordFiles.Length + " " + wordFile.FullName + Environment.NewLine);
                    System.Console.WriteLine("start " + count + "/" + wordFiles.Length + " " + wordFile.FullName);
                    doc = word.Presentations.Open(wordFile.FullName, MsoTriState.msoFalse, MsoTriState.msoFalse, MsoTriState.msoFalse);
                    //word.Activate();

                    string outputFileName = wordFile.FullName.Replace("." + fileType, ".pdf");
                    object fileFormat = WdSaveFormat.wdFormatPDF;
                    Microsoft.Office.Interop.PowerPoint.PpSaveAsFileType targetFileType = Microsoft.Office.Interop.PowerPoint.PpSaveAsFileType.ppSaveAsPDF;

                    // Save document into PDF Format
                    doc.SaveCopyAs(outputFileName, targetFileType, MsoTriState.msoCTrue);

                    strBuilder.Append("end " + count + "/" + wordFiles.Length + " " + wordFile.FullName + Environment.NewLine);
                    System.Console.WriteLine("end " + count + "/" + wordFiles.Length + " " + wordFile.FullName);
                    count++;
                    object saveChanges = WdSaveOptions.wdDoNotSaveChanges;
                    //doc.Close();
                    //((_Document)word).Close(ref saveChanges, ref oMissing, ref oMissing);
                }
                catch (Exception ex)
                {

                    strBuilder.Append(wordFile.FullName + " " + ex.Message);
                    System.Console.WriteLine(wordFile.FullName + " " + ex.Message);
                }
                finally
                {
                    if (doc != null)
                    {
                        doc.Close();
                        doc = null;
                    }
                }
            }
            File.WriteAllText(@"E:\convert-" + fileType + ".txt", strBuilder.ToString());
            // word has to be cast to type _Application so that it will find
            // the correct Quit method.
            ((Microsoft.Office.Interop.PowerPoint.Application)word).Quit();
            word = null;
            System.Console.WriteLine("finish");
            System.Console.ReadLine();

        }
    }

}

//add reference


Thứ Tư, 20 tháng 3, 2019

pdf2htmlEX error while loading shared libraries: libfontforge.so.1: cannot open shared object file: No such file or directory

install libgif4 then install libfontforge1 

https://debian.pkgs.org/8/debian-main-amd64/libgif4_4.1.6-11+deb8u1_amd64.deb.html http://ftp.br.debian.org/debian/pool/main/g/giflib/libgif4_4.1.6-11+deb8u1_amd64.deb 
sudo dpkg -i libgif4_4.1.6-11+deb8u1_amd64.deb 
https://ubuntu.pkgs.org/14.04/ubuntu-updates-main-amd64/libfontforge1_20120731.b-5ubuntu0.1_amd64.deb.html http://archive.ubuntu.com/ubuntu/pool/main/f/fontforge/libfontforge1_20120731.b-5ubuntu0.1_amd64.deb 

sudo dpkg -i libfontforge1_20120731.b-5ubuntu0.1_amd64.deb 
 chieuvh@CPU10777:~/Downloads$ sudo dpkg -i libgif4_4.1.6-11+deb8u1_amd64.deb 
 Selecting previously unselected package libgif4:amd64. (Reading database ... 185021 files and directories currently installed.) 
Preparing to unpack libgif4_4.1.6-11+deb8u1_amd64.deb ... 
Unpacking libgif4:amd64 (4.1.6-11+deb8u1) ... Setting up libgif4:amd64 (4.1.6-11+deb8u1) ... 
Processing triggers for libc-bin (2.23-0ubuntu10) ... 

chieuvh@CPU10777:~/Downloads$ sudo dpkg -i libfontforge1_20120731.b-5ubuntu0.1_amd64.deb dpkg: warning: downgrading libfontforge1 from 20170731-0ubuntu1~xenial to 20120731.b-5ubuntu0.1 (Reading database ... 185031 files and directories currently installed.) 
Preparing to unpack libfontforge1_20120731.b-5ubuntu0.1_amd64.deb ... 
Unpacking libfontforge1 (20120731.b-5ubuntu0.1) over (20170731-0ubuntu1~xenial) ... 
Setting up libfontforge1 (20120731.b-5ubuntu0.1) ... 
Processing triggers for libc-bin (2.23-0ubuntu10) ... 

chieuvh@CPU10777:~/Downloads$ ll /usr/lib/libfontforge.so.1 
lrwxrwxrwx 1 root root 21 Th08 30 2017 /usr/lib/libfontforge.so.1 -> libfontforge.so.1.0.0

 

Thứ Năm, 27 tháng 12, 2018

những bài toán hay

Chả là trong cuộc đời học toán 12 năm của mình, em được tiếp xúc với khá nhiều bài toán hay, cũng tự cho mình là 1 thằng khá thông minh, nhưng cũng khá nhiều bài toán trông thì khá đơn giản nhưng mình không thể giải nổi, nay em post lên đây vài bài xem trình độ của Voz nhà ta thế nào, thím nào mà dùng Google để giải thì ko bằng loài cầm thú 
Anh em ai có bài nào hóc búa thì post lên đây để em cho vào #1



1.Với 3 lần cân trên cái cân roberval ( cái cân mà bên nào nặng hơn nó nghiêng về bên ấy ) , liệu có thể xác định trong 12 đồng xu ( trong đó có 1 đồng có trọng lượng khác không biết là nặng hơn hay nhẹ hơn ) đồng nào bị lỗi ( làm bằng cách đánh số cả 12 đồng xu và xét tất cả các TH, tham khảo #180) - Thử giải bài toán với trường hợp 13 thay cho 12

Nhắc nhở thêm các thím là rất nhiều người nhầm câu này bởi vì các bạc giả dụ đồng bị lỗi là đồng nhẹ hơn rồi sau đó ngộ nhận luôn, chỉ có 3 lần cân và không biết đồng bị lỗi là đồng nặng hơn hay nhẹ hơn





2.Trên 1 chiếc tàu có 4 người :thuyền trưởng, thuyền phó,thuyền viên và bác lao công  , họ có 1 kho báu 1000 đồng tiền vàng và chia như sau, người được chia là người có quyền cao nhất trong số họ, khi người to nhất (ban đầu là thuyền trưởng) đưa ra phương pháp chia tài sản mà có lớn hơn 1 nửa không tán thành thì người đó sẽ bị những người còn lại giết ( được tự vote cho mình), và quyền đc chia số vàng sẽ được giao cho người to thứ 2 ( thuyền phó ), vậy nếu bạn là thuyền trưởng thì bạn sẽ chia làm sao cho số tiền mình nhận đc là lớn nhất, cả 4 người trên thuyền đều cực kì thông minh, tính toán sâu xa và luôn làm điều có lợi nhất cho mình ( hiện tại toàn thấy đoán mò chứ chưa thấy ai đưa ra đáp án hay cách giải đúng )

(xin lưu ý là số tiền các thym cho thuyền trưởng là 500 hay 1 số xxx nào đó, điều đó có thể đảm bào thuyền trưởng không bị giết nhưng đó chưa phải là số lớn nhất thuyền trưởng có thể nhân, bài này rất logic ( bài này khá hay nếu ai chưa từng đc nghe )
update lời giải câu thứ 2, xin lưu ý câu này nên tự làm, làm chán chê không được hãy đọc ở #178




3.Muốn đi qua 1 sa mạc mất 6 ngày, 1 ông chủ muốn đi qua sa mạc cần tối thiểu bao nhiêu người hầu, biết cả ông chủ + người hầu chỉ mang đc tối đa mỗi người 4 suất lương thực ( mỗi suất ăn đc 1 ngày ) ( không thể bỏ người hầu giữa sa mạc đc và mỗi người lúc nào cũng chỉ mang tối đa đc 4 suất ) ( đã có thým giải đúng rồi  ở #50 )




4.Tìm nghiệm nguyên của phương trình a^3 + b^4 = 7 (bài này cách giải khá ngắn + hay ) ( chải ai giải đc,bài này em đọc trong 1 cuốn sách của chuyên toán tin khoa học tự nhiên, google cũng không có đâu, update cách giải #183) 




5.Toán học sinh giỏi lớp 7( hồi ấy cả lớp chỉ có em và 1 thằng nữa dùng pascal để tìm) Tìm 1 số có 6 chữ số : abcdef biết rằng abcdef x 4= fedcba ( bài này dễ nên yêu cầu phải giải nhanh, đã có thým tìm đúng số rồi đó ở #80 và #94)





6.Bài này em đọc cũng khá lâu : Có 51 quân bài, mỗi 1 lượt mỗi người sẽ rút trên bàn từ 1 đến 4 quân bài bất kì( không được quá 4),ai là người rút quân bài cuối cùng trên bàn thì thua, hãy chỉ ra cách để người đi sau luôn là người thắng cuộc ( đáp án #132)





7. Đề thi tuyển dụng vào google ( up cho 1 số thým chưa biết ) Tại một đất nước mà mọi gia đình chỉ dừng sinh con nếu họ đã có 1 con trai, nếu đứa trẻ sinh ra là bé gái, họ sẽ tiếp tục có thêm em bé cho đến khi có bé trai đầu tiên thì dừng lại. Vậy tỷ lệ nam nữ của đất nước này là bao nhiêu? ( đã có thým giải đc,  #32 và #73 )



8Bạn có 10 lọ kẹo. Trong một lọ, tất cả các viên kẹo đều bị chảy nước. Chỉ có bằng cách sử dụng bàn cân, bạn mới có thể xác định được đâu là viên kẹo “bình thường”, đâu là viên bị chảy. Tất cả những viên bình thường đều nặng 10g mỗi viên, trong khi mỗi viên chảy nước chỉ có trọng lượng 9g. Làm thế nào sau chỉ một lần cân bạn có thể xác định được đâu là lọ thuốc hỏng? ( bài này có vẻ hình như cũng thông dụng, nhiều thým biết rồi #73)

9 Trên 2 tấm bảng, 1 tấm bảng ghi tổng bình phương của 2 số tự nhiên, 1 tấm bảng ghi tổng của 2 số đó, người ta đưa tấm bảng thứ nhất cho An và đưa tấm bảng thứ 2 cho Bình, và yêu cầu tìm 2 số đó ( An không biết bảng của Bình và Bình cũng không biết bảng của An )
An : Mình không thể đoán đc
Bình: Mình gợi ý cho bạn là tổng của 2 số nhỏ hơn 10
An: thế mình biết đc 2 số đó là 2 số nào rồi
Bạn 2 cho biết 2 số tự nhiên đó là 2 số nào 


10.Có 500 cái cửa nằm dọc theo một hành lang đánh số từ 1 đến 100. Lúc đầu các cửa đều đóng. Có 500 người xếp hàng đi dọc hành lang. Anh thứ nhất mở tất cả các cửa; anh thứ hai chuyển trạng thái (mở thành đóng, đóng thành mở) các cửa 2, 4, 6, ...; anh thứ ba chuyển trạng thái các cửa 3, 6, 9, ...; cứ như vậy đến anh thứ 500 chuyển trạng thái cửa 500.Hỏi: cuối cùng có bao nhiêu cửa đóng? (đáp án ở #96 )




11 Có 50 viên bi màu xanh và 50 viên bi màu đỏ, có 2 cái lọ giống nhau, bạn đc phép thoải mái cho mỗi lọ bao nhiêu viên bi xanh bao nhiêu viên bi đỏ tùy thích ( chỉ cần tổng số viên của 2 lọ là 100 ), sau đó 1 người khác (không biết cách sắp xếp của bạn) nhắm mắt bốc bừa 1 viên bi duy nhất trong 1 lọ duy nhất, bạn sắp xếp viên bi các lọ thế nào để xác suất người đó bốc đc viên bi đỏ là cao nhất và xác suất là bao nhiêu ??? ( đáp án #116)




12Bài toán của selochome: Một lần Sherlock Holmes đến chơi nhà bác sĩ Watson . Họ ngồi trong phòng khách cạnh một cửa sổ nhìn ra vườn. Từ ngoài vườn , vang lên tiếng cười đùa của một đám trẻ con . 
- anh được mấy cháu ? Sherlock Holmes hỏi .
Bác sĩ Watson : - Trong đám trẻ con nay không phải chỉ có con tôi mà có trẻ của 4 gia đình . Trẻ nhà tôi đông nhất . Con cậu em thứ nhì , con nhà cô em gái đông thứ 3 , cuối cùng là con nhà ong chú ít nhất. Chúng quậy như vậy vì cả đám không đủ để chia thành 2 nhóm 9 người .
Nếu nhân 4 số chỉ số trẻ con của mỗi nhà thì được kết quả chính là số nhà của tôi mà anh đã biết.Sherlock Holmes là 1 thám tử có khả năng suy diễn lôgic rất tốt nên chỉ suy nghĩ vài phút , ông bèn nói : - Anh cho thiếu giả thiết nên không thể biết chính xác được số con của mỗi nhà .Xin hãy cho biết thêm ông chú anh có 1 con hay nhiều hơn ?
Watson trả lời thêm . Sau đó thì Sherlock Holmes đã nói chính xác số con của mỗi nhà .
Hỏi : - Số nhà của bác sĩ Watson ?
- Mỗi nhà có mấy con ? ( bài này giống bài 9, mọi người cố gắng tự giải đừng dùng google nhé)


c)Bài toán vịt ăn tảo ( vừa đi chôm đc  )
Quote:
Bác nông dân cũng có một cái ao đầy tảo và rong biển. Bác nhớ lại là mỗi khi tảo và rong biển mọc đầy ao, bác lại thả lũ vịt xuống cho chúng xơi. Lần thứ nhất bác thả 5089 con và chúng xơi sạch tảo trong đúng 10 ngày. Lần thứ hai (khi tảo lại đầy ao) bác thả 5011 con và chúng xơi hết trong đúng 15 ngày. Bác hứng thú suy luận tiếp: "Vậy thì dựa theo bài toán của Newton, đàn vịt 5001 con năm trước của mình sẽ xơi hết tảo trong vòng hơn 16 ngày! Hay quá! Mình biết làm toán rồi!". Nhưng bỗng một phút, bác sựt nhớ: "Ồ, khoan đã" - bác tự nhủ - "Mình còn nhớ rõ là dạo ấy phải đúng 3 tuần lũ vịt mới xơi hết tảo mà, làm gì có chuyện hết tảo trong 16 ngày" Giả sử mỗi con vịt đều giống nhau, và ăn một lượng tảo như nhau mỗi ngày. Trước tiên, bạn hãy giải thích tại sao có sự mâu thuẫn trong bài toán Newton với bài toán đàn vịt ăn tảo? Câu hỏi chính được đặt ra như sau: Sau nhiều lần mua bán, bác nông dân trên hiện có một số lượng vịt không biết rõ, chỉ biết nếu lùa đàn vịt ấy vào cái ao trên (với đầy tảo) thì chúng sẽ ăn hết trong đúng một số lượng ngày dự kiến. Muốn tảo hết sớm hơn đúng một ngày so với dự kiến thì bác nông dân phải mua thêm khoảng 276 con, trước khi lùa tất cả vào ao. Hỏi đàn vịt bác đang có là bao nhiêu con và nếu không thêm vịt thì chúng sẽ ăn hết tảo trong ao trong bao nhiêu ngày? À, để bài toán đơn giản hơn, mình cho thêm chi tiết là vịt chỉ ăn tảo vào ban ngày và tảo chỉ sinh sản vào ban đêm. Ngày đầu tiên được tính vào đúng 12:00AM (tức nửa đêm).
14 Bài toán của Newton:a)1 cánh đồng cỏ mọc dày như nhau, cỏ luôn mọc đều như nhau trên toàn bộ cánh đồng. Biết rằng 12 con bò ăn hết cỏ trên 10/3 acrơ trong 4 tuần, 21 con bò ăn hết cỏ trên 10 ac rơ trong 9 tuần. Hỏi bao nhiêu con bò ăn hết cỏ trên 24 ac rơ trong 18 tuần?


b)Biết 70 con bò ăn hết cỏ trong vòng 24 ngày, 30 con bò ăn hết trg 60 ngày. Hỏi bao nhiêu con bò sẽ ăn hết cỏ của cánh đồng trong 96 ngày? ( mọi người cố gắng giải thích nhé, đừng đưa mỗi cái đáp án, và nhớ là cỏ luôn mọc chứ không phải bò ăn hết là thôi, giống như ngày xưa có bài toán con ốc sên ngày leo lên đêm trượt xuống )


c


15 Bài của bạn yevon1987 ( mình không biết lời giải đâu nhá):trên đồng cỏ có một con cừu và rất nhiều con sói. tất cả các con sói đều bắt đầu ở trạng thái "đói". nếu một con sói ăn thịt con cừu thì nó sẽ chuyển sang trạng thái "no". vấn đề là khi ở trạng thái "no" thì nó bị coi là yếu hơn các con sói "đói", và nó có thể bị một con sói "đói" ăn thịt. một con sói "đói" nếu ăn thịt một con sói "no" thì cũng sẽ trở thành một con sói "no". biết rằng các con sói đều rất thông minh, đều muốn ăn thịt con cừu nhưng lại không muốn bị con sói khác ăn thịt.

tìm số con sói còn lại nếu số con sói ban đầu là
a. 2011 con
b. 2012 con

Thứ Tư, 26 tháng 12, 2018

Zookeeper Log Parser

package org.apache.helix.tools.commandtools; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.beans.Introspector; import java.beans.PropertyDescriptor; import java.io.BufferedWriter; import java.io.EOFException; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileWriter; import java.io.IOException; import java.text.DateFormat; import java.util.HashMap; import java.util.LinkedList; import java.util.Map; import java.util.Set; import java.util.zip.Adler32; import java.util.zip.Checksum; import javax.xml.bind.annotation.adapters.HexBinaryAdapter; import org.apache.jute.BinaryInputArchive; import org.apache.jute.Record; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.apache.zookeeper.KeeperException.NoNodeException; import org.apache.zookeeper.ZooDefs.OpCode; import org.apache.zookeeper.data.Stat; import org.apache.zookeeper.server.DataNode; import org.apache.zookeeper.server.DataTree; import org.apache.zookeeper.server.persistence.FileHeader; import org.apache.zookeeper.server.persistence.FileSnap; import org.apache.zookeeper.server.persistence.FileTxnLog; import org.apache.zookeeper.server.util.SerializeUtils; import org.apache.zookeeper.txn.TxnHeader; public class ZKLogFormatter { private static final Logger LOG = LoggerFactory.getLogger(ZKLogFormatter.class); private static DateFormat dateTimeInstance = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.LONG); private static HexBinaryAdapter adapter = new HexBinaryAdapter(); private static String fieldDelim = ":"; private static String fieldSep = " "; static BufferedWriter bw = null; /** * @param args */ public static void main(String[] args) throws Exception { if (args.length != 2 && args.length != 3) { // System.err.println("USAGE: LogFormatter log_file"); // System.exit(2); } args = new String[3]; args[0] = "log"; args[1] = "/zserver/zookeeper-3.4.12/zkdata/version-2/log.70228950a"; args[2] = "/zserver/zookeeper-3.4.12/zkdata_parse/log.70228950a"; if (args.length == 3) { bw = new BufferedWriter(new FileWriter(new File(args[2]))); } if (args[0].equals("log")) { readTransactionLog(args[1]); } else if (args[0].equals("snapshot")) { readSnapshotLog(args[1]); } if (bw != null) { bw.close(); } } private static void readSnapshotLog(String snapshotPath) throws Exception { FileInputStream fis = new FileInputStream(snapshotPath); BinaryInputArchive ia = BinaryInputArchive.getArchive(fis); Map sessions = new HashMap(); DataTree dt = new DataTree(); FileHeader header = new FileHeader(); header.deserialize(ia, "fileheader"); if (header.getMagic() != FileSnap.SNAP_MAGIC) { throw new IOException("mismatching magic headers " + header.getMagic() + " != " + FileSnap.SNAP_MAGIC); } SerializeUtils.deserializeSnapshot(dt, ia, sessions); if (bw != null) { bw.write(sessions.toString()); bw.newLine(); } else { System.out.println(sessions); } traverse(dt, 1, "/"); } /* * Level order traversal */ private static void traverse(DataTree dt, int startId, String startPath) throws Exception { LinkedList queue = new LinkedList(); queue.add(new Pair(startPath, startId)); while (!queue.isEmpty()) { Pair pair = queue.removeFirst(); String path = pair._path; DataNode head = dt.getNode(path); Stat stat = new Stat(); byte[] data = null; try { data = dt.getData(path, stat, null); } catch (NoNodeException e) { e.printStackTrace(); } // print the node format(startId, pair, head, data); Set children = head.getChildren(); if (children != null) { for (String child : children) { String childPath; if (path.endsWith("/")) { childPath = path + child; } else { childPath = path + "/" + child; } queue.add(new Pair(childPath, startId)); } } startId = startId + 1; } } static class Pair { private final String _path; private final int _parentId; public Pair(String path, int parentId) { _path = path; _parentId = parentId; } } private static void format(int id, Pair pair, DataNode head, byte[] data) throws Exception { String dataStr = ""; if (data != null) { dataStr = new String(data).replaceAll("[\\s]+", ""); } StringBuffer sb = new StringBuffer(); // @formatter:off sb.append("id").append(fieldDelim).append(id).append(fieldSep); sb.append("parent").append(fieldDelim).append(pair._parentId).append(fieldSep); sb.append("path").append(fieldDelim).append(pair._path).append(fieldSep); sb.append("session").append(fieldDelim) .append("0x" + Long.toHexString(head.stat.getEphemeralOwner())).append(fieldSep); sb.append("czxid").append(fieldDelim).append("0x" + Long.toHexString(head.stat.getCzxid())) .append(fieldSep); sb.append("ctime").append(fieldDelim).append(head.stat.getCtime()).append(fieldSep); sb.append("mtime").append(fieldDelim).append(head.stat.getMtime()).append(fieldSep); sb.append("cmzxid").append(fieldDelim).append("0x" + Long.toHexString(head.stat.getMzxid())) .append(fieldSep); sb.append("pzxid").append(fieldDelim).append("0x" + Long.toHexString(head.stat.getPzxid())) .append(fieldSep); sb.append("aversion").append(fieldDelim).append(head.stat.getAversion()).append(fieldSep); sb.append("cversion").append(fieldDelim).append(head.stat.getCversion()).append(fieldSep); sb.append("version").append(fieldDelim).append(head.stat.getVersion()).append(fieldSep); sb.append("data").append(fieldDelim).append(dataStr).append(fieldSep); // @formatter:on if (bw != null) { bw.write(sb.toString()); bw.newLine(); } else { System.out.println(sb); } } private static void readTransactionLog(String logfilepath) throws FileNotFoundException, IOException, EOFException { FileInputStream fis = new FileInputStream(logfilepath); BinaryInputArchive logStream = BinaryInputArchive.getArchive(fis); FileHeader fhdr = new FileHeader(); fhdr.deserialize(logStream, "fileheader"); if (fhdr.getMagic() != FileTxnLog.TXNLOG_MAGIC) { System.err.println("Invalid magic number for " + logfilepath); System.exit(2); } if (bw != null) { bw.write("ZooKeeper Transactional Log File with dbid " + fhdr.getDbid() + " txnlog format version " + fhdr.getVersion()); bw.newLine(); } else { System.out.println("ZooKeeper Transactional Log File with dbid " + fhdr.getDbid() + " txnlog format version " + fhdr.getVersion()); } int count = 0; while (true) { long crcValue; byte[] bytes; try { crcValue = logStream.readLong("crcvalue"); bytes = logStream.readBuffer("txnEntry"); } catch (EOFException e) { if (bw != null) { bw.write("EOF reached after " + count + " txns."); bw.newLine(); } else { System.out.println("EOF reached after " + count + " txns."); } break; } if (bytes.length == 0) { // Since we preallocate, we define EOF to be an // empty transaction if (bw != null) { bw.write("EOF reached after " + count + " txns."); bw.newLine(); } else { System.out.println("EOF reached after " + count + " txns."); } return; } Checksum crc = new Adler32(); crc.update(bytes, 0, bytes.length); if (crcValue != crc.getValue()) { throw new IOException("CRC doesn't match " + crcValue + " vs " + crc.getValue()); } TxnHeader hdr = new TxnHeader(); Record txn = SerializeUtils.deserializeTxn(bytes, hdr); if (bw != null) { bw.write(formatTransaction(hdr, txn)); bw.newLine(); } else { System.out.println(formatTransaction(hdr, txn)); } if (logStream.readByte("EOR") != 'B') { LOG.error("Last transaction was partial."); throw new EOFException("Last transaction was partial."); } count++; } } static String op2String(int op) { switch (op) { case OpCode.notification: return "notification"; case OpCode.create: return "create"; case OpCode.delete: return "delete"; case OpCode.exists: return "exists"; case OpCode.getData: return "getDate"; case OpCode.setData: return "setData"; case OpCode.getACL: return "getACL"; case OpCode.setACL: return "setACL"; case OpCode.getChildren: return "getChildren"; case OpCode.getChildren2: return "getChildren2"; case OpCode.ping: return "ping"; case OpCode.createSession: return "createSession"; case OpCode.closeSession: return "closeSession"; case OpCode.error: return "error"; default: return "unknown " + op; } } private static String formatTransaction(TxnHeader header, Record txn) { StringBuilder sb = new StringBuilder(); sb.append("time").append(fieldDelim).append(header.getTime()); sb.append(fieldSep).append("session").append(fieldDelim).append("0x") .append(Long.toHexString(header.getClientId())); sb.append(fieldSep).append("cxid").append(fieldDelim).append("0x") .append(Long.toHexString(header.getCxid())); sb.append(fieldSep).append("zxid").append(fieldDelim).append("0x") .append(Long.toHexString(header.getZxid())); sb.append(fieldSep).append("type").append(fieldDelim).append(op2String(header.getType())); if (txn != null) { try { byte[] data = null; for (PropertyDescriptor pd : Introspector.getBeanInfo(txn.getClass()) .getPropertyDescriptors()) { if (pd.getName().equalsIgnoreCase("data")) { data = (byte[]) pd.getReadMethod().invoke(txn); continue; } if (pd.getReadMethod() != null && !"class".equals(pd.getName())) { sb.append(fieldSep).append(pd.getDisplayName()).append(fieldDelim) .append(pd.getReadMethod().invoke(txn).toString().replaceAll("[\\s]+", "")); } } if (data != null) { sb.append(fieldSep).append("data").append(fieldDelim) .append(new String(data).replaceAll("[\\s]+", "")); } } catch (Exception e) { LOG.error("Error while retrieving bean property values for " + txn.getClass(), e); } } return sb.toString(); } }