xxx-bridge-disbursement.txt 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. How to hand out bridges.
  2. Divide bridges into 'strategies' as they come in. Do this uniformly
  3. at random for now.
  4. For each strategy, we'll hand out bridges in a different way to
  5. clients. This document describes two strategies: email-based and
  6. IP-based.
  7. 0. Notation:
  8. HMAC(k,v) : an HMAC of v using the key k.
  9. A|B: The string A concatenated with the string B.
  10. 1. Email-based.
  11. Goal: bootstrap based on one or more popular email service's sybil
  12. prevention algorithms.
  13. Parameters:
  14. HMAC -- an HMAC function
  15. P -- a time period
  16. K -- the number of bridges to send in a period.
  17. Setup: Generate two nonces, N and M.
  18. As bridges arrive, put them into a ring according to HMAC(N,ID)
  19. where ID is the bridges's identity digest.
  20. Divide time into divisions of length P.
  21. When we get an email:
  22. If it's not from a supported email service, reject it.
  23. If we already sent a response to that email address (normalized)
  24. in this period, send _exactly_ the same response.
  25. If it is from a supported service, generate X = HMAC(M,PS|E) where E
  26. is the lowercased normalized email address for the user, and
  27. where PS is the start of the currrent period. Send
  28. the first K bridges in the ring after point X.
  29. [If we want to make sure that repeat queries are given exactly the
  30. same results, then we can't let the ring change during the
  31. time period. For a long time period like a month, that's quite a
  32. hassle. How about instead just keeping a replay cache of addresses
  33. that have been answered, and sending them a "sorry, you already got
  34. your addresses for the time period; perhaps you should try these
  35. other fine distribution strategies while you wait?" response? This
  36. approach would also resolve the "Make sure you can't construct a
  37. distinct address to match an existing one" note below. -RD]
  38. [While we're at it, if we do the replay cache thing and don't need
  39. repeatable answers, we could just pick K random answers from the
  40. pool. Is it beneficial that a bridge user who knows about a clump of
  41. nodes will be sharing them with other users who know about a similar
  42. (overlapping) clump? One good aspect is against an adversary who
  43. learns about a clump this way and watches those bridges to learn
  44. other users and discover *their* bridges: he doesn't learn about
  45. as many new bridges as he might if they were randomly distributed.
  46. A drawback is against an adversary who happens to pick two email
  47. addresses in P that include overlapping answers: he can measure
  48. the difference in clumps and estimate how quickly the bridge pool
  49. is growing. -RD]
  50. [If we make the period P be mailbox-specific, and make it a random
  51. value around some mean, then we make it harder for an attacker to
  52. know when to try using his small army of gmail addresses to gather
  53. another harvest. But we also make it harder for users to know when
  54. they can try again. -RD]
  55. To normalize an email address:
  56. Start with the RFC822 address. Consider only the mailbox {???}
  57. portion of the address (username@domain). Put this into lowercase
  58. ascii.
  59. Questions:
  60. What to do with weird character encodings? Look up the RFC.
  61. Notes:
  62. Make sure that you can't force a single email address to appear
  63. in lots of different ways. IOW, if nickm@freehaven.net and
  64. NICKM@freehaven.net aren't treated the same, then I can get lots
  65. more bridges than I should.
  66. Make sure you can't construct a distinct address to match an
  67. existing one. IOW, if we treat nickm@X and nickm@Y as the same
  68. user, then anybody can register nickm@Z and use it to tell which
  69. bridges nickm@X got (or would get).
  70. Make sure that we actually check headers so we can't be trivially
  71. used to spam people.
  72. 2. IP-based.
  73. Goal: avoid handing out all the bridges to users in a similar IP
  74. space and time.
  75. Parameters:
  76. T_Flush -- how long it should take a user on a single network to
  77. see a whole cluster of bridges.
  78. N_C
  79. K -- the number of bridges we hand out in response to a single
  80. request.
  81. Setup: using an AS map or a geoip map or some other flawed input
  82. source, divide IP space into "areas" such that surveying a large
  83. collection of "areas" is hard. For v0, use /24 address blocks.
  84. Group areas into N_C clusters.
  85. Generate secrets L, M, N.
  86. Set the period P such that P*(bridges-per-cluster/K) = T_flush.
  87. Don't set P to greater than a week, or less than three hours.
  88. When we get a bridge:
  89. Based on HMAC(L,ID), assign the bridge to a cluster. Within each
  90. cluster, keep the bridges in a ring based on HMAC(M,ID).
  91. [Should we re-sort the rings for each new time period, so the ring
  92. for a given cluster is based on HMAC(M,PS|ID)? -RD]
  93. When we get a connection:
  94. If it's http, redirect it to https.
  95. Let area be the incoming IP network. Let PS be the current
  96. period. Compute X = HMAC(N, PS|area). Return the next K bridges
  97. in the ring after X.
  98. [Don't we want to compute C = HMAC(key, area) to learn what cluster
  99. to answer from, and then X = HMAC(key, PS|area) to pick a point in
  100. that ring? -RD]
  101. Need to clarify that some HMACs are for rings, and some are for
  102. partitions. How rings scale is clear. How do we grow the number of
  103. partitions? Looking at successive bits from the HMAC output is one way.
  104. 3. Open issues
  105. Denial of service attacks
  106. A good view of network topology